ASP.Net - Generating Secure Tokens - token

I am working on an authentication library for my website, and I want to use a token based authentication system, but I don't have a clue how to generate a secure session token so that I could identify users. Does anyone have any resources that would point me in the right direction?

A random authentication token could be enough depending on the kind of architecture you have.
Or you could use GUIDs, ... There are a lot of possibilities, here is one:
When the user authenticates, generate a random token, add it into a cookie on the user system and into the database. When the user comes back, the unique random token is searched in the database so you can establish the link between the random token and the user. Tada !

Related

How to authorize logged in users using Google Auth JWT? (Picture)

I currently have a backend running on AWS Lambda and I'm using DynamoDB as a database. In Dynamo, there is a list of users and each user has specific permissions as to what routes they have access to through the API. There is no issue here.
I have not built the front end yet, but I will be logging in users using Google Auth, more specifically with the react-google-login component.
My question is: Once a user is logged in to the site, should I trust the JWT from Google (after verifying its legitimacy
here with the Google API) which returns the user information (Name, Email), lookup the user item inside of Dynamo to retrieve their permissions, and then serve their request?
This seems like the logical thing to do but I was looking for some confirmation. My one worry is that someone could use a supervisors name & email to authorize a request but if the lambda must accept a JWT created by Google as entry, I believe this problem is solved correct?
I have API Keys as well for every user for some external functionality, but I have that covered since it's just a Dynamo call away. My only concern is with the front end requests to Lambda since I do not want to roll my own auth/jwt.
Here is what I was envisioning.
Thank you!
Normally you should use access tokens for that purpose. The ID token should be meant only to authenticate the user, and the access token should be used to authorize access.
The best scenario would be to have a separate Authorization Server which could issue access tokens, and there are some open source solutions out there which you can use.
If you really don't want to setup your own AS then you could follow the scenario you outlined - the part with verifying JWT from Google and checking permissions in the DynamoDB is what the Authorization Server would normally do to issue an access token.
Just remember to thoroughly validate the incoming JWT - not only the signature with Google, but also check if that is a token created for your client / audience, etc. Otherwise someone could take a Google ID token JWT from their client and gain access to your API. This article lists best security practices when working with JWTs.
Also remember that ID tokens might have short expiration times and there are no means of automatically refreshing them (like you can do it with a refresh token in case of an access token), so you might end up having to reauthenticate quite often.

Why is it recommended to give magic link JWT tokens a shorter TTL than those delivered through HTTP and why one-time?

I'm looking to create an application that never uses passwords and want to understand the risks.
Magic Link guides often suggest giving the JWT token a short TTL and to implement one-time use.
A Compromised email account seems to be a mute point because a password can be retrieved using a password reminder. We already depend on email accounts. Furthermore the security around email is far superior (device recognition for example) than most self-built applications.
Passing the JWT token as a query string parameter is not a risk if you use HTTPS, which I would.
Imposing one-time use means maintaining server side token database - one of the reasons for using JWT is not having to do this.
Adopting passwordless means that every time people want to log in they have to go through the email roundtrip which isn't that great UX but is it acceptable?
Once they have gained access all future auth is managed through JWT as usual.
Am I missing something?
You can implement a refresh token which last longer and an access token for a short period so that the user has to log in few times

User profile information store in JWT or use API

In my application, I have separate microservices for user authentication and user profile information. The user authentication service is using Spring Security OAuth2/JWT. Once a user successfully logs in, a JWT token is issued with the user unique identifier.
My query is how other services should retrieve user profile information. Should I put this information (such as first name, last name etc) into the JWT token or should I create an API on the user profile service which retrieves the user profile information once the token is retrieved?
Any best practice advice would be appreciated.
So far most approaches i've seen was to store only user's login in JWT token and have another service which gives you other needed informations by login, and this seems like the best approach to me (in case of any security leak's login is the only thing that can be stolen, and not user's first or last name).
I think it is important to highlight that OAuth2 is intended to be an authorization protocol rather than authentication.
OpenID Connect solves this problem by separating the identity (ID_Token) and the authorization (access token) into two different tokens for the application to consume. Rather than implementing your own, may I suggest that you consider OpenID Connect?
I have had similar discussions with my team while working on the authentication microservice. Though it's important to understand that JWT is an encoding and not an encryption so it's always advised not to keep sensitive data in JWT. Though the items that we decide to keep in JWT should also depend on the problem statement we are solving. There can be use cases where saving the Username or email id is not a sensitive information and you may want to keep that in JWT just to avoid an extra API call.

Use an encrypted token or not?

For API authentication based on a token: What is the advised practice:
Save the token in the dabase encrypted or unencrypted?
For authentication: find the user based on the token (only possible if the token is stored in the database unencrypted) or based on for example the user's email address?
I found several sources that seem to store an unencrypted token and then in authentication find the user on basis of the token received with the API request. That seems somewhat insecure to me, since then the back end searches the entire User table on basis of the token included in the request, irrespective which user has that token (so someone could just try out many tokens). At the same time I don't know if it it necessary to encrypt the token.
I'd treat it as a password - encrypt it.
Then when user connects, you look up the user specified, you encrypt the provided token and compare the results for that user.
The main reason, is when you get hacked, you don't have to reset everyone's compromised tokens immediately when you restore, you should have a little more time.. as the hacker won't have access to their tokens.. and if your token is salted, may never.
Not that I'd advocate not resetting the token! Just, it's one less immediate issue in the heat of the moment.

How do you prevent session hopping using ASP.Net Web API?

Creating an angularjs single page application trying to use a RESTful API and I came across a problem that I can't seem to find an answer for. I was trying to prevent session hoping, one user logged in watching the requests figures out his account ID is 13. So he performs the same request but this time alters the request to get info for account ID 14.
So after the user logged in I was setting a session variable to his account ID and was going to strip the account ID out of the ajax requests. I then tried to access the Session from a class inheriting from ApiController. After looking around I realize that storing session information is not very RESTful.
So how would I go about ensuring that one account cannot access another account's information just because they watched the ajax requests and figured out how to manipulate the ajax request?
Is restful not meant to be used with users that need to authenticated and authorized? I was thinking of maybe hashing the IDs or something but I am not sure that is the right approach.
UPDATE:
I have token based authentication working now. But I am still in the dark as to how to prevent someone from fiddling with HTTP request and getting information that doesn't belong to him. For Example, I want to retrieve all the users for account with ID 14.
HTTP Get /users/14
I have a token so I know that the person trying to use the web API at some point authenticated themselves. I can lock it down to roles. But there is nothing stopping this authenticated person form fiddling/hacking with the request and doing the following
HTTP Get /users/58
Now the person has got all of account with ID 58's information. This is information does not belong to account 14 but now he can browse through other people's information.
I need someone of knowing that the request that comes from the browser and says it is for account with ID 14 that it really is account 14. I can put that information in the token but how do I check it in a handler or check it in the ApiController?
The problem you have described is not something unique to REST-based services. In fact, this is one of the top 10 OWASP vulnerabilities (Insecure Direct Object References). You will need to first identify the user and then authenticate the user. For identification, an ID is used, such as user ID. The identifier can be anything you want. After identification, you need to authenticate the user. This is done by authenticating the credential presented to the app, such as password. The identifier and the credential can be any thing, say the good old user name/password, or may be a token or may be an API key. It actually does not matter to the problem on hand. Once authenticated, you authorize the requests based on what the user can do in your app. The authz part is a must regardless of whether you use a token, certificate or what not. Hashing user ID or using some method to hide things is security by obscurity and is not a good practice.
Say, you are using a message handler to authenticate the credential submitted by a user. Once authentication is done you can store the account number associated with the authenticated user in the properties collection of HttpRequestMessage. This is done in the server side and no user can make the system store some random account number. Only the account number associated with the authenticated user is stored in the properties collection. With that, you can now authorize requests. Say, you can write an authorization filter that pulls this account number and compare it against the account number in the URI to determine if the request is allowed or not. By applying this filter against a GET action method, you can ensure only right folks can see right data.
For example, a user with user ID 'abc' and password 'pwd1' makes a GET request to /users/14. First step is, you will authenticate the user ID. If there is a user with ID 'abc' and password 'pwd1' in your store, you will consider the user authentic. As part of this authentication, you can pull the account number associated with the user 'abc'. Say it is 15. You will store 15 in request.properties. From your authorization filter, you can get the account number from URI, which is 14 and compare it against the one in the request, which is 15. Obviously the numbers do not match and you reject the request in the OnActionExecuting method of your filter with a 401.
What I described above is a simple approach. Better one (in terms of extensibility) will be to use claims but it will not be possible to explain all that here. You can get good amount of information related to claims-based identity from Dominick's blog.
Every request should be authenticated. If the credentials provided do not allow the user with account 13 to access data from account 14 then the request will be denied. The trick is to find a way to do authZ quickly.
You seem to be missing the information on how you want to implement authentication. As you correctly noted, using session to keep authentication information is not very restful. Here are the alternatives
Implement your own OAuth provider or use third party (for example
Azure ACS)
Implement STS provider (this is only for soap though)
Implement a custom token system, if you don't want to deal with
the above two. Basic system would take user id, salt it and encrypt with private key - but don't quote me on how secure that would be...
In all the cases, the authentication information is stored in the cookie, similar to session cookie. But it is still stateless.
The standard way on the web seems to be the oauth way, in fact the standard VS MVC template even comes with OAuth consumer implemented out of the box. So the question is, how do you link the oauth token to your internal user ID. That's really pretty simple, as you implement the "registration" step after the new user is authenticated - you keep user ID and oauth token in the database table, to link the two.
That link is quick to retrieve, and can be cached for speed. I have heard some people implement that type of credentials caching for some very big systems (google docs).

Resources