I have implemented a spring boot application which does authentication and authorization using Spring OAuth2.
I am using JDBC token store to main the token issued to the client for performing Custom claim verification and some other user status verification during application run-time.
The question is, since i had used traditional JSESSIONID with CSRF token, i cannot find any advantage with the new OAuth standards because after login i would store the user details in the session and retrieve it whenever needed similarly for OAuth i store the User details in the JWT token itself and decode the token every time to get the user information, also i need to hit the database anyway for custom claim verification such as JTI verification .
Everyone says JWT is for stateless application but with JDBC token store i'm holding all the token that is issued to each client. Also there is an additional overhead to purge the expired token which will be done automatically with Session. Also i'm using refresh token as the way to implement session timeout.
Therefore can anyone explain me, when should i use JSESSIONID and when to use JWT ? My application is running on AWS architecture.
From my experience, cookie-based authentication sufficiently complicates scaling and load-balancing. If you have authenticated via the first service replica, your cookie will be not appliable to another replica, cause all sessions are stored in memory. So, if you want to scale your service in the future, session-based authentication can make things much more complex.
Related
I'm implementing security for my React SPA using Spring Security on the backend. After a lot of reading, I opted for the following approach :
HTTPS everywhere
POST /login takes credentials returns JWT_TOKEN & XSRF_TOKEN in cookie form. I build the JWT_TOKEN myself whereas Spring Security handles the XSRF_TOKEN. Both cookies are Secured and SameSite=Strict. The JWT token is HttpOnly.
Subsequent API calls require the X-XSRF-TOKEN header. This is read from the aforementionned cookie. Both are sent and Spring Security compares them. JWT is automatically sent and checked in a Filter.
Every time a XSRF token is used, Spring Security generates a new one to prevent session-fixation attacks
XSS protections are applied by Spring Security
So now I'm wondering about refresh tokens. I'm reading a lot of contradictory info out there. Do I need them with this setup? If so how best to handle this ?
Many Thanks
In general, as its name says, the refresh token changes from one token to another. Typically they are used in OAuth protocol-based authentication. They are useful when an access token has expired, but the user's session is still valid.
First, JWTs are a great choice for access tokens. They have claims that match the access tokens requirements, such as: exp, iat, jti, sub, etc. But, when using a cookie-based authentication there is no need for access tokens and possibly no need for JWT.
As you said, your JWT_TOKEN is being set as an HttpOnly cookie, which means that only the server has access to it. JWT is useful for sharing the initial state between the client and server, and vice-versa. If your server is just taking it to look up the database, you don't need a JWT, you are just using a session concept, and keeping session data on a JWT may not be a good practice.
Second, if your authenticated cookie data will live at /login and die at /logout, there is no need for refresh tokens. Refresh tokens are an exchange key for short-life access tokens. Instead, your cookies keep the session live and don't need to be exchanged by something else.
For example, if the user uses the /login route to exchange your username and password for one short life access_token. He may need the refresh_token to get a new access_token without needing to send his username and password again.
If you are using the OAuth protocol or similar, refresh tokens are essential to provide a more seamless experience for your users and avoid the inconvenience of repeatedly having to re-enter their credentials. But even on OAuth, they are not mandatory.
Am I correct in the following thought process?
For a native app I'm building I want to implement a backend in Spring Boot.
This backend will be secured using Spring Security. Since I will manage and develop everything myself (the backend, the native app(s) and the web app for backend management) securing everything with JWT would be sufficient and implementing a full oauth server would be a bit overkill.
I have implemented the JWT token generation in my backend at this moment. On user sign in, the backend returns a json object containing some user details as well as an access token and a refresh token. The access token will be short lived, the refresh token will be long-lived (speaking about months of life time, maybe even indefinite unless revoked).
Is it correct that the refresh token could theoretically also be used as the access token? Or should I set some value/data in the refresh token that identifies it as a refresh token only (so can't be used to access resources, only to generate new access token)?
I have two authorization server application ( spring boot 2.0.5 ).
The two authorization server application are similaire
When a user ask for a token, spring will register a session for that specific user and give back a token, with that token you can access to the resource of application 1 but you can't access to the resource of application 2.
My question is if there is a way to share the same security context in addion when you generate token from application 1 you can use to access of application 2 resource
What you can do is to make your applications stateless when it comes to security.
What does it mean?
Spring Security will no longer generate a session for a new logged in user. When the user logs in, you will issue him a token (e.g. JWT). Each time when the user accesses secured content, he/she will have to provide a token and your applications will verify that token with a public or private key (depending on which type of token encryption you will use - symmetric or asymmetric). In the end, you will not need to share anything, if both of your applications have same keys to verify incoming tokens.
Some tips:
A token you send upon each request to access secured resources is called "access token". Make it expirable and make it short lived (like 15 mins). Why? This token cannot be immediately invalidated unlike session which can be simply deleted. In case if someone hijacks it, it will be still able to access secured resources.
Since your "access token" is short lived, it would be annoying for a user to logs in every 15 minutes. To prolong its life, you can have another type of token called "refresh token" that can be stored in some database. This token can be immediately invalidated by simply deleting it from the database. Therefore, if someone even hijacks it, user will be able to revoke it and the hijacker will not be able to prolong his session.
References: Stateless authentication with JWT
We are also facing similar problem.
For web pages we are using SSO which cache token in clientContext and using Authorization-server-1
For making call to API-1 we are using token generated by Authorization-server-2. In this case we have create another session bean for clientContext and that is caching token (having its own oauth2RestTemplate and clientCredientialResource)
This is two legged scenario
We doing research, how to use three legged scenario for calling web/rest service, but we were not able to do so, as access token retrieval is two step process (using authorization code) and call back will execute the whole method again and not continue from line after call to rest api
I have been following a tutorial to create a Spring SSO application which uses Facebook for authentication but creates its own access tokens to secure back-end resources.
The sample application creates a user on first login and stores the user's facebook token for further use (getting data from facebook later on).
My question is that how do I handle token expirations? When the facebook token expires, how do we setup spring security to refresh it? What about our application's token expiration?
You can find my sample project here.
The app in the tutorial only uses the token for authentication (i.e. it uses it once when the user logs in to get the user's personal details), so it's highly unlikely to expire in the time it is being used. Having said that, the OAuth2RestOperations instance that is used to carry out that single request is capable of refreshing the token on its own (if the provider sent it a refresh token and allows the access token to be refreshed by your client).
If I'm implementing an authentication layer in my app using a mix of JWT and Redis to store session data, do I need to include an expiring in the JWT token itself?
For example, when you login to the app, a session id is generated and added to the redis database with an expiry of 3 days. Then that session id (along with username) is used to create the JWT payload. On all auth requests, I make sure the session id from the token exists in the redis database. If it doesn't, the session has expired and I issue a new token.
Are there security issues with this implementation?
No security issues but one may argue that by including an expiry field in the JWT, the Redis layer can be made obsolete. In principle the JWT allows the application to become stateless. If your application is going to store all of its session data in Redis anyhow (because the JWT would be too large for that) one may argue that the benefit of using a JWT over a plain random session identifier is gone.
Bottom line: the exp field in a JWT is optional and you are free to implement another mechanism to achieve the same.
It depends on how you implement your authentication/authorization layer.
Your authentication/authorization flow is stateful, thus expiration is very coupled with the session. I would include expiration just to let consumers of the whole JWT know when is going to expire and take actions based on this information.
There's also the stateless approach where there's no session identifier and there's no server storing information, but the JWT is self-descriptive, containing expiration and other data as claims. Since the consumer of the JWT relies in the JWT producer, and communications are secured by using a transport-level security approach like HTTPS/SSL, there's no need to maintain state but the state is the JWT itself.
One of most well-known and standarized autentication/authorization flows is OAuth2. I would say that you should build your security layer on top of industry standards. This is good because you avoid a lot of R&D, security holes and time.