I have application with backend and frontend. We are using JWT token for the authentication and Authorization(A2). Now we are planning to use express-gateway as an API gateway (AG) so that backend can be unload from routing and other protection heavy load and shift that burden to AG. Now since we are using AG shall we remove the A2 logic from backend and whatever request comes to backend (every request will be routed from consumer to backend via AG) we treat it as authenticated user and process the request, no need to verify again. If yes then we will still need JWT token to get the payload to extract the information like email id, role etc. For that should we pass the token from AG to backend. Also backed might have different kind of things on payload than EG. How to tackle that.
To pass authentication information on to a server, you need to use the request-transformer policy to add the information to the request headers going to the server, e.g. the following fragment adds a header named eg-consumers-firstname:
- request-transformer:
- condition:
name: authenticated
action:
headers:
add:
jscode: 'req.headers["eg-consumer-firstname"] = consumer.firstname'
The JS variables you can use in jscode sections is not particularly well documented, but you have access to everything in models/users.js.
In general, you can often adjust the gateway.config.yml such that scopes restrict which apiEndpoints (paths) are available to a given user; this is a better way to prevent unauthorized access then doing the processing on the downstream server side, which should do an independent check in case the API gateway has been compromised.
Related
I have an xAPI content made by storyline I want for the statement to be sent to a webapp instead of the LRS.
this webapp is developped using laravel, and user should be authenticated with email and password to use it.
what I did to send the statement to this app:
1.in the webapp I created an API endpoint route that use POST method.
2.in the xAPI wrapper I changed the endpoint in the configuration to the route I made in the webapp.
const conf = {
"endpoint":"here I added my api endpoint route of the webapp",
"auth":"Basic " + toBase64(""),
}
now whith any interaction with the content where a statement should be sent the request making cors error like in the picture down, I think this is authentication error, how can I add my authentication credentials to the xAPI wrapper?
Your non-LRS LRS is probably not handling preflight requests which are necessary for CORS handling. Most common LRSs will handle those requests appropriately since they expect to be accessed from additional origins. See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests
Also note that you'll likely run into issues unless you also handle state requests.
Additionally unless you are requesting the credentials from the user during runtime then hard coding the credentials into the package isn't a great idea from a security perspective.
I've been doing some HTTP methods and header research recently if we should use GET with basic authorization instead of POST when submitting?
HTTP Methods
The GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
The POST method submits an entity to the specified resource, often causing a change in state or side effects on the server.
As we see here, the POST method normally changes the state of the server. If sending out JWTs/HTTP cookies, we are not modifying the state of the server. Nor are we creating a new resource in the server.
I understand that we should not not send the username and password as a GET parameter but should we use the authorization header instead?
Basic authentication
For "Basic" authentication the credentials are constructed by first combining the username and the password with a colon (aladdin:opensesame), and then by encoding the resulting string in base64 (YWxhZGRpbjpvcGVuc2VzYW1l).
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
The only advantage I see to using POST over GET is that we need no extra code in the HTML/JS on the client side to send headers via the fetch API. To send headers, we would need an onsubmit and then check if status code is 200. If 200, we will need to redirect to the page after the login screen. Then again, if using the fetch API, this means the server does not need to send a new HTML page to the client all the time either.
Should we use GET with basic auth or POST when logging in since we don't create a resource/modify the server state?
Would this change if say we enable 2FA since we would need to generate a code for that user?
Doing basic authentication in the browser and using GET is not that recommended.
To do your own login form it is better to always do it using HTTPS and POST. Do post the username/password in the body of the request and secure it with proper CSRF protection.
If you want to level up, you can always look at the OpenIDConnect approach, but that is more advanced depending on your needs.
Also, a good approach is to explore how existing site implement a login form and look at the HTTP(s) traffic in a tool like Fiddler.
As per the documents received writing down the flow of authorization for version 4.0:
1. call authorize service to get the authorization code back.
2. read the 'code' value for the authorization_code.
3. use this authorization_code to get 'access_token' using '4.0/oauth/token'.
4. for the subsequent calls use 'access_token'.
Please confirm if my understanding above is correct.
My question:
- What will happen when access_token expires? Do we need to go to above flow again?
- the URLs are https does it need certificates?
- what will be the redirect_uri if i want to test in my dev?
I suggest reading a bit about OAuth 2.0 flow. Here's a decent article/example that I would start with from Digital Ocean: https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
But to answer your specific questions:
when the access_token expires you need to make an additional request to Social Tables with the refresh_token -- here's an example: click here. In short, yes you need to use the refresh token to get a new access token which you'll use for subsequent requests
No, you do not need to configure any certificates on your end. These are done via SSL+HTTPS and are ready to go.
The redirect_url for local development can be set to your local running server. You can set it to http://localhost:<port> and that will work just fine.
My app is using Angular2 for the front-end, served by a separate (cross domain) backend server running express and using passport.js for Google Oauth authentication.
When a user is authenticated by the server using Passport (through google oauth), their user data is loaded from the database and included in the credentials, which is used to determine which backend API routes they are authorized to use. (It's based off this tutorial on scotch.io that I'm sure everyone has seen: https://scotch.io/tutorials/easy-node-authentication-setup-and-local )
I want to access this user object in my front-end as well to enable route-guards that depend on a user's access level (defined in their user object on the server).
From this question it seems the data is sent via a JWT and is readable on the front-end, just not changeable, which is fine: https://www.reddit.com/r/Angular2/comments/4ud0ac/ng2_secure_connection_front_to_back/
How do I access and read that token on the client? All I can find is the 'connect.sid' session cookie set by express. The payload of the cookie doesn't fit a standard JWT as it only has 2 sections, not 3.
You are probably not using JWT but cookie-based sessions if you followed the tutorial. The cookie only contains a session ID which your server uses to identify the session from the session store, and using this information you probably dig up something from the database in deserializeUser. That is then available to you in req.user in the backend.
You could of course add the user data to the response of every request but if you really are using cookie-based sessions sending the user object with every response likely makes little sense. You could eg. just add a route that will return the relevant parts of req.user:
app.get('/users', function(req, res) {
res.json({ username : req.user.username });
);
I have this scenario: a corporate site (MVC 4) and a web shop; add OAuth 2 SSO functionality. Both sites have their own members, but the corp site (for which I'm responsible) must also work as an OAuth 2 authorization server and will store a web shop user id for each member. The shop requested the following endpoints:
Auth endpoint
• authorization:
…/oauth2/authorize?client_id={CLIENT_ID}&state={STATE}&response_type=code&redirect_uri={REDIRECT_URI}
• token
…/oauth2/token?code={TOKEN}&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&redirect_uri={REDIRECT_URI}&grant_type=authorization_code
…/oauth2/token?refresh_token={TOKEN}&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&redirect_uri={REDIRECT_URI}&grant_type=refresh_token
API endpoint
• getid (will return JSON with the shop id of the member):
…/oauth2/api/getid?access_token={TOKEN}
I don't have experience with OAuth, so I was looking at the DotNetOpenAuth samples and have concluded that I need to implement an OAuthAuthorizationServer, but modifying the sample to fit my requirements is difficult as it seems to do more and is complex.
As researching DotNetOpenAuth seems to be so time consuming, I'd like to ask: is modifying the OAuthAuthorizationServer sample the right approach? Or should I try to make a native implementation or try a different OAuth library that may be easier to use in my situation?
Please comment on my overall plan:
-keep the corp site member login flow standard forms auth, straightforward LogOn controller
-add an OAuth controller that will implement the three required endpoints as actions
-when the authorization action is reached, I validate the client and redirect to LogOn passing on the redirect_uri; I think the Authorize ActionResult from OAuthController.cs from the sample is where I should start investigating this, and return an AccountAuthorizeModel. Is this correct?
-after the user logs in, and if the login page was reached from the authorization endpoint, I redirect to redirect_uri with the code attached; I don't know where to start with this one. PrepareApproveAuthorizationRequest then PrepareResponse? Where does the code come from? Where in the flow should I add a new ClientAuthorization in the database?
-the shop will then use the code to get or refresh the token, from the /token endpoint; simply return HandleTokenRequest?
-with the token the shop site will be able to get the member data JSON; have to find out how to validate the token
Now, besides adding a Clients table to store the client ids and secrets, and ClientAuthorization to keep track of who's authorized, I don't know if the other tables from the DotNetOpenAuth sample are used and when: Nonce, SymmetricCryptoKey, User.
Modifying OAuth2AuthorizationServer.cs seems straightforward, I only have to add real certificates and make sure the clients are pulled from my data context.
Thanks!
I think you are right in most of the points. Let's comment them:
OAuth server should have 2 endpoints (not 3), as requesting token and refreshing token goes to the same endpoint (TokenEndpoint).
It depends if your are going to implement a different authentication server (or controller), or you are going to implement the authentication responsibility inside the authorization server. In case they are separated, the authentication server should be the one responsible of displaying the logon, authenticate and communicate with authorization server using OpenID protocol (Also supported by DotNetOpenAuth).
Once the user is authenticated, the authorization server should store the data of the user identity somehow, and return the authorization code (if using this Oauth flow) using DotNetOpenAuth functions:
var response =
this.AuthServer.PrepareApproveAuthorizationRequest(AuthorizationRequest,
User.Identity.Name);
return this.AuthServer.Channel.PrepareResponse(response);
finalResponse.AsActionResult();
I don't think you need to save nothing about the authorization process in the database, and the code is generated by DotNetOpenAuth and sent to the client into the query string of the redirection.
Then, the client should get the code (ProcessUserAuthorization) and call the TokenEndpoint. This endpoint is just returning HandleTokenRequest, that internally is calling to some OAuthAuthorizationServer functions, such as CreateAccessToken.
Once the client has the access token, it should call the resources, sending the token into the HTTP Header 'Authorization'. The resource server is the responsible to validate the token.
var resourceServer = new ResourceServer(new
StandardAccessTokenAnalyzer(signing, encrypting));
AccessToken token = resourceServer.GetAccessToken(request, scopes);
A store provider for nonce and crytoKeys is needed using this flow. Have a look to class InMemoryCryptoKeyStore in:
https://github.com/DotNetOpenAuth/DotNetOpenAuth/wiki/Security-scenarios
Hope this helps!