Does it make sense to store JWT in a database? [closed] - spring

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
The community reviewed whether to reopen this question 10 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I've implemented a basic authentication system with Spring Boot, Spring Security, OAUTH2 and JWT as auth tokens. It works alright but I was thinking if it makes sense to store JWT in a database and check if a token exists every time someone makes an authenticated request using it? I was thinking specifically of the following scenario: user is authenticated in a mobile device and they lose it so they want to deauthorize that device. They would then be able to issue an operation that clears the tokens issued to their user id and deauthorize all tokens assigned to him. Any other way? Am I thinking this wrong or overcomplicating things?
This is for securing a REST API that is going to get called from a mobile APP.

You could store the JWT in the db but you lose some of the benefits of a JWT. The JWT gives you the advantage of not needing to check the token in a db every time since you can just use cryptography to verify that the token is legitimate. If you have to look up the token in the db, you might as well just use an opaque token that doesn't carry information with it and let the server and database provide you with the information. On the other hand, if you're going to store a token in the db, I don't think a JWT is a bad choice for your token type. As you say, there are advantages for revocation if you store your token in the db. It all depends on what you want to achieve (faster authorization, etc. vs ability to revoke on demand).
You can still use JWT with OAuth2 without storing tokens in the db if you want. JWTs have a configurable expiry time that you can set--after which they are invalid. Access Tokens (whether JWT or not) should usually be short-lived for security. If the concern is someone's phone being stolen and access tokens being obtained, I think the solution is to have those tokens expire quickly (30 mins?). If you're using oauth2, the means of stopping someone from continuing to use the app is for the real owner to de-authorize the mobile app client on the authorization server so that no more access tokens will be given out.

You can set expiration date (for mobile 1 week).
Add some custom field refreshId for user (you can use uuid for this).
Next set Issued at claims parameter ("iat").
Store refreshId into db and set it as claims parameter .
Then every time when you validate token you should check the token's "age". If it older than one hour you should load data from DB and check refreshId value and create new token with current "iat" value and send it to mobile device. When you need to deactivate tokens just generate new value for refreshId in db. After one hour all tokens will be incorrect, so user will need to login on every device again. You can make more custom solution if you need to.

Related

How to create endless session for mobile app

Current situation
We have a very common system architecture with Spring Boot back-end and Angular front-end. For the mobile app we use Ionic, which basically uses same codebase as the front-end but adds additional features like biometrics etc.
User login is based on OAuth and access and refresh tokens are created once the user initiates the session. The access token has a short life span, where the refresh token is valid for a couple of days. As I said - very common auth flow.
What we want to achieve
Mobile app users should be able to login only once and then use the
app without the need to re-login every time the refresh token
expires.
For the "normal" front-end app refresh token expiration
policy should stay unchanged, meaning the user is forced to log in
again once the refresh token expires.
Possible solutions (from my perspective)
we pass an additional param to the login request specifying the client: web | mobile. If client is mobile refresh token validity is extended to expire in 1-2 years. Downside: this will break the whole idea of having tokens, that expire. I personally see this as a security issue.
we store credentials on mobile app local storage. Once we have session expiration, the app uses the credentials to re-authenticate. Downside: again I don't think this is a good idea having credentials stored on any device makes the flow vulnerable.
What I am looking for is kind of a best practice to solve this.
You are right, It's a security risk to have tokens that never expire or expire in a few years but they are used. Anyway, one thing you could do is to add a field in the refresh token endpoint that when you set it to true (defaults to false) it would also extend the lifespan of the refresh token. And you could periodically call that endpoint from your app. It should work even when It's in the background.
Or
If you wanna store the credentials in the local storage at least store them encrypted. You might need to create an endpoint that encrypts them because you should not have the private key in the mobile app. Then you'll probably need to create a custom authentication method that takes the encrypted credentials and compares them with the ones in the database.

Spring Boot, OAuth2 Custom Auth Server [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am trying to venture into the full-stack development realm during some of my free time, and I just have a few general questions about my current understanding of OAuth2. I am very green when it comes to this stuff, but I've watched some Udemy videos to gain a basic understanding.
Anyway... this project that I'm working on, I'm planning on having a custom authorization server, a resource server, and a single client (which will likely be a SPA). This authorization server will only allow the authorization code (probably with the PKCE extension) grant type. Which leads me to my first general question...
Intuitively, I assumed that the password grant type would be sufficient. As I've done more and more reading, it looks like this grant flow is not the way to go. As I understand it, using this flow would require the client to provide some form so that the user may login. Doing so gives the client access to user credentials, which very much defeats one of the purposes of OAuth2. I'm not sure this is an issue with what I'm developing, however, because I am creating the authorization server. I know by using this grant flow, I am not validating the client. Can someone explain how this might be an issue? Is there anything else I'm missing here? Everything I've read has deterred me from using this grant flow, which is mostly why I ended up deciding on the authorization code (w/ PKCE) flow.
So... assuming I go with this flow, my client should provide a login button. Pressing this login button will re-direct the client to a web page where the resource owner can authorize the client and provide user credentials. My authorization server will then validate these user credentials. I plan on storing user credentials in a database on the VM running the auth server. I don't plan on allowing users to register an account. Instead, I'm just going to have a static list of account credentials in this database for people on my team. So I guess I'm just going to insert these accounts when the database is created? If so, how do I allow these users to change their passwords? I guess I'm thinking that initially these accounts will be assigned an e-mail, username, and random password that I can communicate with them. However, I'd like the user an option to change this random password to something more familiar. I don't currently know how to do something like this with the OAuth2 implementation. Do I just provide a way in the client to change the password when the user is logged in? If so, doesn't this somewhat defeat the purpose of using OAuth2 as now my client would have knowledge of the user credentials? If I were to do this, however, would this just be implemented as a POST request to a REST API at the auth server for updating the password?
I would start by using a free cloud provider as the Authorization Server. Have a look at the following tutorial of mine, which uses Authorization Code Flow + PKCE:
Blog Post
Easy to run SPA and API Code Sample
This sample uses AWS Cognito which is a fast option for getting started. It will enable you to create users - they will then be prompted to change the password on the first login.
The important points are these:
Write simple standards based code in your apps and spend time learning the recommended flows and design ppatterns
Once code is written you should be able to switch to a different Authorization Server later, if needed
Avoid building your own Authorization Server, and use one that has been provided by specialists
You should only need Spring for the resource server (my API above uses Node.js). If you want an easy to follow Spring resource server sample maybe see this one.

Does token auth make sessions unnecessary?

My question may be answered here, Are sessions needed for python-social-auth, but I feel as if I'd be making assumptions and would like to be positive regarding my understanding (NOTE: I'm not using django, I'm using mongo express react node, I'm guessing django might come with sessions built in or something). I followed this guide https://medium.com/hyphe/token-based-authentication-in-node-6e8731bfd7f2 to add token authentication and user login to my CRUD web app, works great, users are authenticated properly, routes are protected. However, everywhere I read about the fundamentals of session and session management states that "every web application in the world that maintains user data has to deal with sessions" (source: https://nodewebapps.com/2017/06/18/how-do-nodejs-sessions-work/). Currently, my react client uses setInterval to regularly check if the access token will expire soon enough to receive a new one via the refresh token. Is implementing sessions required for my app? If so, what is it that they add that I am missing?
It depends on the type of application.
If the resources being accessed using a token are not user specific, then sessions are not useful.
However, in a scenario where the resources are unique for different users (e.g. one has to sign in, etc), then it's wise to implement both sessions and access tokens.
Remember that tokens can also be saved within a session. Checkout 'express-session' to implement sessions in expressjs.

When using IdentityServer, what is the best practice of saving/accessing external claims from Google?

My IdentityServer application is configured to use Google login. I am using OIDC. This question is about external claims.
At login time, my application has access to all of the claims Google sends back from the auth request. I can access them in my custom implementation of UserServiceBase in the method AuthenticateExternalAsync (via the context). I can even add them to the AuthenticateResult object so when GetProfileDataAsync gets executed after the user has accepted the consent, I can access them via the ProfileDataRequestContext.Subject.Claims list. But this is the last point they will be in memory.
If I do not save these claims in a database, how can I access them once the login process is over? I want to keep my id_token simple so I do not put claims (other than sub) in the token. So I need to call the /userinfo end point to get the claims, but by this point they are no longer in memory.
What is the cleanest way of getting these claims back? To be clear, I want to get the claims from Google when the user calls /userinfo and translate them to the claims naming convention of my application. (I do not want to store them in the id_token at login time if possible... as per OIDC spec)
Note: This question is similar to mine, but that does not address how to do it using IdentityServer3.
Yes, you will need some persistence mechanism for the claims from the external provider. You should already have this, as the subject claim that you are issuing from IdentityServer should be unique to your token service (and not the unique id google gives you).

Yammer OAuth Impersonation Token Storage

I have started building a C# asp.net website that will have the ability to post directly into Yammer (we have Yammer Enterprise). I have used the REST api to create a post and have also been able to create in impersonation token to post on behalf of other users. It works fine, but reading the documentation, the tokens seem to have an indefinite lifetime. Forgive me is this is a stupid question, but is there an expectation that as a developer, I should store the token locally (eg in a SQL table) and reuse local version for future API calls?
If the API call fails, then I assume I regenerate the token and re-store for future use?
Thanks
Andy
Yes, these tokens don't expire until an account is suspended or deleted in Yammer, or the user manually revokes the app. Until that changes you need to be very careful with handling these tokens. Applying encryption, permissions, and other techniques to secure your app is the best way to protect them.
You might also consider storing the time when the token was acquired or last used. Then delete the token after a period if it hasn't been used. That will protect the user.
In your UI make it clear what your app does with Yammer so that users authorizing it are aware of what they are opting into.

Resources