Implementing JWT with Spring security using random username - spring-boot

I'm currently planning to use JWT to secure my API, I have read several tutorials, and find that generally, it's using username and password to generate token, while the UserDetail is got and constructed from a database.
Now I have a question, if I cannot get the UserDetail for some reason, can I use some random data, like UUID replacing username, to identify each request?
update:
I feel if I just use the token to distinguish per request, actually it's not so called oauth2, it's just JWT token.
Actually previously our solution is, we generate a token and store it in Redis before each request , then we verify if the token expires in Redis in each request.
As the customers don't need to login to purchase something, we don't have UserDetail info, Now I feel almost no difference between two solutions, and I'm even wondering if the JWT token alone gives better security.
^_^

Related

What to return after login via API?

I'm creating an API server which will be consumed by a mobile app that I will work on later. I have yet to see any reference of API best practices related to user flow and returned data even after searching for several hours.
My question is whether the login response of an API should return the a personal access token with the refresh token along with the user info? Or should I just return the token and make another API call for getting the user info.
I could just do what I have in mind but I'm trying to learn the best practices so that I don't have to adjust a lot of things later.
I need suggestions as well as good references related to my question.
Thank you.
It depends on what you are using for your authentication. If you are using libraries like Laravel Passport or JWT, you can have the token endpoint which returns the access token, refresh token, validity period and the token type (Bearer). You can then have an authenticated endpoint which will be used to get a user's profile based of the token passed in the request header.
However, if you go through the documentation for those libraries, in most there is an allowance to manually generate a token. You can use this in a custom endpoint that will return the token as well as the user profile Passport Manually Generate Token.
If you are using JWT, you can also embed a few user properties in the token itself. The client can the get the profile info from the JWT itself without having to make a round trip to the server. Passport ADD Profile to JWT
If you have a custom way in which you are handling authentication, you can pass the token as well as the user profile in the same response.
In the end, it's up to you to decide what suits you best.
Have you looked at OpenID Connect? It's another layer on top of OAuth 2.0 and provides user authentication (OAuth 2.0 does not cover authentication, it just assumes it happens) and ways to find information about the current user.
It has the concept of an ID_token, in addition to the OAuth access token, and also provides a /userinfo endpoint to retrieve information about the user.
You could put user information in your access token, but security best practice is to NOT allow your access token to be accessible from JavaScript (i.e. use HTTP_ONLY cookies to store your access token).

Oauth2 hash token on Auth Server

I'm implementing an Auth server using Spring Security Oauth2. What I noticed is that when spring security saves the access token (using JdbcTokenStore) , the OAuth2AccessToken is serialized as which means the access token is self is saved as plain text. I have a couple questions about this.
1.) The token is never actually retrieved using the access token value. It is retrieved using a token id. Why is that?
2.) Is it Ok to hash this token since it is never retrieved using it's value?
3.) Do we actually need to generate the token id? Can we pass an extra information from the resource server to the authentication server to retrieve the token and validate it against the hash?
By default Spring stores the token in plain text. If you make a request to get a token again in the same browser, you will notice that Spring will return the same token as long as it is still valid.
1) This is not entirely correct. On the resource server, the token is read from the header and a PreAuthenticatedAuthenticationToken is created. Through several steps the token value is used to create the OAuth2Authentication. The key is a intermediate step, but only after you have resolved the token to an OAuth2AccessToken (see TokenStore.readAccessToken())
2) Personally I would hash the token before storing it in the database! This does however require you to implement/extend a TokenStore, since you need to override TokenStore.storeAccessToken() to save the hashed value, and TokenStore.readAccessToken() to hash the incoming token and find the hash in the database.
3) Typically the authentication server and resource server read the same database, and both ends up with a OAuth2Authentication identifying the user. If you want to hash, you just need to implement the store/read methods as described above.
I have implemented a solution like this with Spring Oauth2 1½ ago, so hashing tokens and refresh tokens is diffidently possible. In our case we ended up not using the resource server implementation from Spring Oauth2, because we get 20K requests every minute, and we wanted to delay resolving the token until the request has been validated, and use several layers of caching to avoid hitting the database on every request.

Is it feasible to use a Guid as an OAuth2 access token?

I am trying to see if I could get my OAuth2 provider to return a Guid as an access token. I am aware that there are existing and well-defined token providers and formats.
The resulting token would look like this:
{
access_token: "a31b99f9-01d7-7165-09be-73d5b7655f15",
expires_in: 1799,
token_type= "bearer"
}
I don't need to support claims and the rest of the authentication details will be stored somewhere in the back-end for when I need to validate it (check the expiry, retrieve additional details, etc). I'm just wondering if it's a feasible option as well?
Yes. Tokens maybe passed by "reference" as long as the Authorization Server supports OAuth 2.0 Token Introspection.
a GUID is not a token. The token includes information which you need to be able to retrieve and work with, otherwise what's the point in having it? The token includes information such as when it expires for example, among other things. If you don't know when the token expires how do you work with it?
You can use a GUID as your ClientID or ClientSecret ( or both ) for example, but that's about as far as you can take it.

Blocking specific user JWT tokens?

Say a user logged in multiple times from different devices, and then they decide they want to logout of device a, we have no way of deleting the JWT which was provided to that device right?
Here is what I've implemented, I'm not sure if this is how other sites do it or if it's a decent way of doing it.
User logs in
I create a redis session token, which has the userId + device name associated to it
I store this redis token as the subject of the JWT
I pass back the JWT.
Now that the user has a JWT, they can now access secured api endpoints. Lets say the user wanted to remove this session, here is what I've done.
User fetches * redis session tokens for the particular userId (of course they need a valid jwt to fetch this data)
They choose the redis session token which they want to destroy.
They send that token to a /destroy/{token} endpoint
The jwt which uses that has that token as the subject will not work anymore.
Doing it this way means on each request, I'll have to decompile the jwt, grab the redis token, and see if it still exists. I guess this isn't expensive todo at all using redis, or any other in memory DB.
Is this a solid/efficient way of doing this? Are there any better/easier ways of doing this?
While implementing JWT authentication/authorization in several apps I also had this same question and reached the same solution if not a very similar one:
In my case, I would store the JWT + UserID + DeviceName in the database, and then I would have an HTTP Request
DELETE /logout/DeviceName with a header Authorization: JWTGoesHere.
This gives me two benefits:
I can now logout a user from any device using a valid JWT (it does not need to be exactly the same JWT, it only needs to be a JWT for that user).
Makes possible the implementation of "Logout all sessions except this one".
In terms of speed, the applications we've developed receive hundreds of requests per second.
More than 90% of these requests need to be authorized, which means checking that the JWT is syntactically valid, checking existence against the database and last but not least check if it's expired.
All these checks (using Redis as the database) take less than 10ms.
Bottom line is: Benchmark it, and if it doesn't take really long then it doesn't need any optimization.
Hope it helps!

Using JWT to implement Authentication on Asp.net web API

I have been reading about JWT.
But from what I read it is not an authentication mechanism but more like a crucial component in a Authentication mechanism.
I have currently implemented a solution which works, but it was just to try out JWT and see how it works. But what I am after now is how one should make use of it. From my experience of it its basically just an encryption mechanism that gives you a unique encrypted key. You are also able to put information inside of this token.
I am wanting to implement it in terms on a ASP.NET web api 2 to be consumed by a mobile application.
So step 1:
app => Server : Login (user, pasword)
Server => app : Login OK, heres your JWT
app => server : Get my profile (sends JWT with request)
Server then decrypts JWT and determines the requests Identity.
Now this is just my understanding of it, Look I could be on the totally wrong path.
Is the Ideal of JWT so that you dont have to authenticate on every request? I just authenticate the users credentials once (on the initial login) and there on after the server can simply use JWT and no have to lookup the users pw and user in the DB?
I just want to use the JWT to Identity who the user is. I will then authorize then after i have authenticated them. As I know there is a big confused with the new MVC and Authentication and Authorization.
So what my question comes down to.
How can I safely and effectively Implement a Authentication Mechanism Using JWT?
I don't want to just cough something up that seems to work and not have any Idea of the security implications. I am sure that there exists a source some where that has possibly designed a secure mechanism that would suit my requirements.
My requirements are:
Must only have to check db for users credentials once off per session? Due to the use of bcrypt using a lot of resources to compare passwords.
Must be able to identify the user from their request. (I.e who they are, userId will be sufficient) and preferably without accessing the DB as well
Should be as low overhead as possible, with regards to resources on the server side processing the request.
If an intruder had to copy a devices previous request, then he should not be able to access the real users data. (obviously)
Thanks
Your understanding of JWTs is good. But here are a couple corrections and some recommendations.
Authentication and Authorization
JWTs have nothing to do with authentication. Hitting your DB and hashing passwords only happens when you authenticate on creation of the JWT. This is orthogonal to JWTs and you can do that in any way you like. I personally like Membership Reboot, which also has a good example of using JWTs.
Theoretically, you could have the user enter a password once a year and have the JWT be valid that entire year. This most likely not the best solution, if the JWT gets stolen at any point the users resources would be compromised.
Encryption
Tokens can, but don't have to be encrypted. Encrypting your tokens will increase the complexity of your system and amount of computation your server needs to read the JWTs. This might be important if you require that no one is able to read the token when it is at rest.
Tokens are always cryptographically signed by the issuer to ensure their integrity. Meaning they cannot be tampered with by the user or a third party.
Claims
Your JWTs can contain any information you want. The users name, birthdate, email, etc. You do this with claims based authorization. You then just tell your provider to make a JWT with these claims from the Claims Principle. The following code is from that Membership Reboot example and it shows you how this is done.
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var svc = context.OwinContext.Environment.GetUserAccountService<UserAccount>();
UserAccount user;
if (svc.Authenticate("users", context.UserName, context.Password, out user))
{
var claims = user.GetAllClaims();
var id = new System.Security.Claims.ClaimsIdentity(claims, "MembershipReboot");
context.Validated(id);
}
return base.GrantResourceOwnerCredentials(context);
}
This allows you to control with precision whom is accessing your resources, all without hitting your processor intensive authentication service.
Implementation
A very easy way to implement a Token provider is to use Microsoft's OAuth Authorization Server in your WebAPI project. It give you the bare bones of what you need to make a OAuth server for your API.
You could also look into Thinktecture's Identity Server which would give you much easier control over users. For instance, you can easily implement refresh tokens with identity server where the user is authenticated once and then for a certain amount of time (maybe a month) they can continue getting short lived JWTs from the Identity Server. The refresh tokens are good because they can be revoked, whereas JWTs cannot. The downside of this solution is that you need to set up another server or two to host the Identity service.
To deal with your last point, that an intruder should not be able to copy the last request to get access to a resource, you must use SSL at a bare minimum. This will protect the token in transport.
If you are protecting something extremely sensitive, you should keep the token lifetime to a very short window of time. If you are protecting something less sensitive, you could make the lifetime longer. The longer the token if valid, the larger the window of time a attacker will have to impersonate the authenticated user if the user's machine is compromised.
I've written detailed blog post about configuring the OWIN Authorization server to issue signed JSON Web Tokens instead of default token. So the resource servers (Audience) can register with the Authorization server, and then they can use the JWT tokens issued by Token issuer party without the need to unify machineKey values between all parties. You can read the post JSON Web Token in ASP.NET Web API 2 using Owin
For the formal concept . The Authentication is the process of verifying who a user is, while authorization is the process of verifying what they have access to.
Let’s see the real life example
Imagine that your neighbor has asked you to feed his pets while he is away. In this example, you have the authorization to access the kitchen and open the cupboard storing the pet food. However, you can’t go into your neighbor’s bedroom as he did not explicitly permit you to do so. Even though you had the right to enter the house (authentication), your neighbor only allowed you access to certain areas (authorization).
For more detailed and for users who like more STEP BY STEP implementation on practical use of JSON Web Token in WEB API. This is must read post Secure WebAPI Using JSON WEB TOKEN
Updated to use: System.IdentityModel.Tokens.Jwt -Version 5.1.4

Resources