Where to store JWT Access Tokens in SPA (i.e. Angular App) - security

Last couple of days, i spent on an issue that how could i secure my jwt access token at client side (browser). Some blogs say that Local / Session storage is not secure to store the token. I moved to store the token in ngrx store but there is another issue that when user refresh the page, he/she must re-login to get the token again. Third option is cookie, a secure and http-only cookie.
Where to store my jwt token to secure it?
Note: In backend, a spring boot api is running which sends a token on successful login.

Related

how to secure JWT both client and server

I'm using JWT authentication for my back-end system written with Django rest frame work,
I've read many articles about JWT security but I have some question yet,
our solution for not saving the access token in browsers local was that we save the refresh token in cookie and client request access token with this cookie in every request for not saving access token anywhere,is this approach save enough?
what can I do for server side?for example is using dynamic secret key for JWT a good idea?
I mean create an secret key for each user and use it for token.or any idea that can secure our system.

Access Token and Refresh Token Dilema - JWT

I have a dilemma following the use of Access Token with Refresh Tokens.
Let's say we have the following scenarios:
User Login -> An access token valid for 5 minutes is returned and saved in local storage. At the same time, a refresh token valid for 3 months is saved in cookies with httpOnly and secure properties. The application will use the access token to get access to resources and after 5 minutes when it expires it will automatically use the refresh token to generate a new access token. After 3 months the user will be asked to log in again.
User Login -> An access token valid for 3 months is saved in cookies with httpOnly and secure properties. The application will use this token to get access to resources and after 3 months the user will be asked to log in again.
What is the point in using method 1 instead of method 2?
Nothing. If you can do #2, then you should, and it's more secure. JWTs are vastly overused, in case of #2, your access token is almost like a plain old session id, why not just use a session id then? (The only reason could be real statelessness, but in many cases the application is not stateless anyway, for example if you want to be able to revoke tokens.)
What you cannot do with #2 is sending the access token to a different origin, and that is actually needed sometimes. Imagine you app is hosted on example.com, but your api is exampleapi.com. If you stored your access token in a cookie, it could not be sent to the api. What usually happens in a more generic case is you have a refresh token (almost like a session, but without server-side state) with the identity provider that can issue tokens on idp.example.com, that's the domain of the secure, htponly cookie. This issues a jwt that your app downloaded from www.example.com can use on api.example.com or wherever else, because the access token is stored by javascript (eg. in localStorage). The point is the token can be accessed by javascript (xss), but it's short-lived, and xss requires user interaction, so it's not easy for an attacker to issue a new access token without the user doing something. The refresh token is stored more securely in a httponly cookie.
If you don't want to send your tokens to a different origin, a httponly cookie is actually better, and you're right, a refresh token doesn't make much sense then. Note though that if the token is stored in a cookie, you will have to mitigate csrf too.

Generating refresh tokens and access tokens in node server

I'm building mobile and a web app. Both apps will be talking to a node server. I am using JWT for authentications.
Currently, I have the following code to generate an access token:
const token = jwt.sign({ user: body }, "top_secret");
I have some questions about access and refresh tokens:
How to create a refresh token?
What do refresh token look like?
Can I create a refresh token - similar to the way I'm creating an access token?
Is the refresh token only used to generate a new access token?
Can the refresh token be used as an access token?
How do you invalidate an access token
How do you invalidate a refresh token? Examples I've seen used databases to store refresh tokens. The refresh tokens are deleted when you want to invalidate an access token. If the refresh token would be stored in the database on the user model for access, correct? It seems like it should be encrypted in this case
When the user logs into my application, do I send both access token and refresh token? I read somewhere (can't remember where) that it's not good practice to send an access token and refresh token.
If its bad practice to send both access and refresh tokens, when do you send a refresh to the client? Should there be an endpoint where the clients request an access token?
What's a good expiry time for access tokens and refresh tokens?
Please note that in typical OAuth2 scenarios, the server issuing tokens (authorization server) and the API server consuming access tokens (resource server) are not the same. See also: Oauth2 roles.
To answer your questions:
How to create a refresh token?
You generate a string of sufficient entropy on the server and use it as a primary key to a database record in the authorization server. See refresh token syntax.
What do refresh token look like?
From https://www.rfc-editor.org/rfc/rfc6749#section-1.5,
A refresh token is a string representing the authorization granted to the client
by the resource owner.
The string is usually opaque to the client.
Can I create a refresh token - similar to the way I'm creating an access token?
You can, but refresh tokens are typically not structured tokens (like JWT) since they're consumed by the same server that issued them.
Is the refresh token only used to generate a new access token?
yes
Can the refresh token be used as an access token?
no
How do you invalidate an access token
Unless you're using introspection tokens, there's not a good way to invalidate them. Just keep their lifetime short.
How do you invalidate a refresh token? Examples I've seen used databases to store refresh tokens. The refresh tokens are deleted when you want to invalidate an access token. If the refresh token would be stored in the database on the user model for access, correct? It seems like it should be encrypted in this case
Delete if from the authorization server store. If the refresh token cannot be found on the server, it cannot be used to refresh an access token. A refresh token is typically just a primary key to a database record holding data about the client, user and expiration of the refresh token. While you don't want to leak your refresh token, it typically does require the client using them to present client credentials to use it.
When the user logs into my application, do I send both access token and refresh token? I read somewhere (can't remember where) that it's not good practice to send an access token and refresh token.
The user signs in at the authorization server. It returns an access token and refresh token (if your client is confidential) to the client. The client uses the access token alone to access your data on the resource server.
If its bad practice to send both access and refresh tokens, when do you send a refresh to the client? Should there be an endpoint where the clients request an access token?
Your client uses the refresh token in a call to the authorization server to get a new access token. So your client sends only the access token to the resource server and only the refresh token to the authorization server.
Whats a good expiry time for access tokens and refresh tokens?
That depends on your threat model. When your refresh token expires, the user is forced to authenticate again. Some products use refresh tokens that never expire, others use refresh tokens that are only valid for hours or days.

Logout from multiple systems in SSO (Single Sign On)

I am implementing SSO for our systems in order to centralize the user authentication and authorization, in which we will have a SSO-server (User and Session Manager) where the user logs in using his/her credentials and then will be able to access all other associated systems.
The implementation of SSO:
First the user will get the session (access token + refresh token)
and they will be stored in the client side.
If he redirects
to the other systems a (single use token) will be generate by SSO
server for that system
And up on the system loading the (single use
token) will be exchanged with a pair of access-token and refresh
token and they will be stored in the client side of that particular
system
And on each server request the session (access token +
refresh token) will be sent through request header so that the
system's server could request this user's authorization from SSO
server.
Access token has less expiry time than refresh token and it's not stored in SSO server and only it's signature is checked for authorization but the refresh token is stored so that we could revoke it later if needed.
(due to the huge amount authorization requests that we will have later on I did not want to stored the access token.)
The problem is that if a user wants to logout, all his/her access tokens should be expired but they are not stored in database and only in client side for each system and I can only revoke the refresh token so the token remains valid until it's expiry time passes and till then it can be used and it means the user is still login.
I use JWT for the token generation and verificaiton.
This is my first question in here I hope I have explained the problem properly.
And I will be waiting for your kind responses.
Preferably use a cookie to store your tokens. When the user has logged out. Simply clear the cookie and return. Now the user does not have the access token and won't be authenticated.
Note: Make sure to make a secure cookie.

What is the workflow for validating a refresh token and issuing a new bearer token?

This is not a coding question, but a conceptual question for the correct handling and processing of a refresh token.
I have a single page app which issues a jwt token when logging in. The token works just fine. Now, I want to set the expiration to a low value, and use a refresh token to refresh the bearer token.
The question is, what claims should be stored in the refresh token? And what steps are supposed to be done to validate the refresh token before issuing a new token?
For example, right now my refresh token is a jwt which stores an expiration, so the client knows when the refresh token expires, and a username claim so that I know what user the refresh token is associated with.
So then when the refresh token is recieved:
Check that it is not expired.
Check that it has not been revoked.
Use the UserName in the refresh token to issue a new short-lived bearer token.
Is this the correct workflow for this? I just want to make sure I am not missing any security checks.
If your application is a single page application, you should not use long lived refresh tokens as you have no way of securely storing them.
OAuth2 defines a number of grant flows for different types of clients (which I've described here). Refresh tokens are only meant for confidential clients (like web applications living on a secured server).
Your refresh token is just as vulnerable to theft as your access token, since both are bearer tokens stored on the client.
Some OAuth libraries allow SPA or other non-confidential clients to get a new access token by talking to the token endpoint of the authorization server using a session token in a cookie. As long as the cookie is valid, the user can get a new access token. After that, the user will need to re-authenticate. Of course cookies can be marked secure and http only, making them harder to steal.
If you issue the JWT tokens from the same service endpoint that consumes the access tokens, you could have the client include a nonce in the token request that you hash and include as a claim in the token. The client can send the JWT in the Authorization header and the nonce in a custom header. Your token verification would hash the nonce again and compare it to the claim in the JWT. That way, if your token is stolen is harder to use without the nonce value. Of course, in a targeted attack, your nonce could also be stolen.

Resources