Cache OAuth2 tokens in SpringBoot application? - spring-boot

I am implementing a Spring Boot application, in which the methods are calling third party REST endpoints. This REST API is accessible after OAuth2 authentication. That is why I retrieve tokens from the third party (various users can use my application and respectfully call the REST endpoints) and use these tokens for authorization in order to call the endpoints. But in the current implementation this happens before every call. That is why I would like to ask for advice how to cache these tokens and whether this is a good practice at all? Also the tokens expire in 1 hour.

You should not cache access tokens on the backend of a web application ,if you can store them client side and send them with each request.
In case you don't have possibility to store it at client side (possible case your API is talking to some message client like USSD,SMS etc),It will be expensive to get an OAuth access token, because it requires an HTTP request to the token endpoint. This case is a good example where you can cache tokens whenever possible.
You can make use of REDIS if you have multiple instances.
REMEMBER : Tokens are sensitive data, because they grant access to a user's resources. (Moreover, unlike a user's password, you can't just store a hash of the token.) Therefore, it's critical to protect tokens from being compromised. You can make use of encryption.Do check below links for more details :
https://auth0.com/docs/best-practices/token-best-practices.
https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md#5-obtaining-and-storing-access-tokens-to-call-external-apis
https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/token-cache
As per Auth0 Token Best Practices
Store and reuse.
Reduce unnecessary roundtrips that extend your application's attack surface, and optimize plan token limits (where applicable) by storing access tokens obtained from the authorization server. Rather than requesting a new token, use the stored token during future calls until it expires. How you store tokens will depend on the characteristics of your application: typical solutions include databases (for apps that need to perform API calls regardless of the presence of a session) and HTTP sessions (for apps that have an activity window limited to an interactive session). For an example of server-side storage and token reuse, see Obtaining and Storing Access Tokens to Call External APIs in our Github repo

Related

Custom JWT token in springboot microservices

We have an application that loads information(user specific) from the external system upon successful authentication, to avoid round trips to the external system for each api call, we are planning create a custom JWT token with user specific information for the first time user authenticated, then the token is send to user in each response header using http interceptor and in the front-end we are including the custom token in every request along with authorization token. Is this correct approach? Do you have any alternative suggestions?
I have looked into other distributed caching techniques like redis but not so appealing for a small usecase. Our payload length does not exceed 4 to 5K hence inclined towards the JWT option
it is ok to include user information that allows you to handle the user authorization inside the access token. Just beware of the privacy implication and perhaps not include personal information like social security number or date-of-birth or other identifiable information.
Also, make sure the token size does not get to big. The other option is to lookup and cache the user information in the API's when it receives a new access token.
Some systems including ASP.NET Core do store the token inside the session cookie in an encrypted form, so that the end user can't see or access the stored tokens.
If you are developing a SPA application, the using the BFF pattern is one approach.

Session vs JWT Token in nodejs with large payload

I am working on a nodejs project and coming from a PHP background. I am pretty impressed with frontend and backend development separately and communicating with API calls.
# Issue: I need to authenticate the user and store some data of the user (which is always needed in the server), this user data which results in increased jwt payload size and jwt token will be large.
So I used JWT token mechanism, generated a token after successful login and send it to the client, then the client add that token as the header with every API call - then verifies token in server and gets the decoded payload data.
This is the process. But I have some user data that is needed always in nodejs, so the JWT payload size increases and JWT token size also large size. So client always sends with large size token everytime.
I was using sessions in php to maintain user data.
If I use sessions for authentication, it will be stateful, right?
# Doubts:
Is there any way to maintain the logged in user data in the server?
How to reduce the length of JWT token if I use large payload?
Updated:
Also if I am using sessions, it makes use of the database to store sessions So a DB call is needed.
What if I use small payload token (eg: userid) for authentication and after authentication make a DB call with userid to get details?
In both methods DB call is needed? Which method seems better?
Using sessions would introduce server state, but lets you keep user data and session data on the server. Only the session id has to be shared with the client.
You cannot reduce the length of the JWT token. Larger payload means a larger token. In theory you could use some kind of compression, but that would be a very high technical overhead and probably not worth it.
Saving sessions on the server would solve your problems.
It also gives the server complete control over the sessions. When the user logs out, the server can delete the session. When the client deletes his JWT token, you cannot be absolutely sure that the user is logged out. The token itself is still valid.
Using JWT as a sessions container is generally a bad idea. This just introduces several security issues, that you have to handle yourself. You have to make sure that 3rd party JavaScript does not read the token, just to name one issue. There are many blog posts, which explain these issues in detail (search for "Stop using JWT for sessions"), but I can only advise not to use JWT for sessions. Sessions are not a bad thing!

Killing "session" with SignalR, OWIN, and Web API

It has been a long road but I have SignalR working with my Web API which uses OWIN for token authentication.
I have a mechanism where if a user authenticates on terminal #1 and then later authenticates on terminal #2, I can send them a Javascript alert saying "Hey, only one session at a time. Which one do you want to log out?"
The question I have is how to kill their "session" on one of the terminals? I say "session", but since this is a REST based API there really is no session. If I could force them to re-authenticate on the terminal they choose to "log out" from that would be sufficient.
I have the SignalR connectionId of each client. Is there a way I can expire their authentication token and force a logout?
Note - The client is separate from the Web API in that they are hosted on two different servers. The client is just HTML/Javascript making calls to the Web API.
If you are using a bearer token approach, and you are not storing tokens (or token hashes) into some kind of persistent storage (e.g. a DB), then you have no way to invalidate a token.
Since OAuth is not an Authentication protocol, it do not have any kind of log out concept in it. Your only option is to remove the token from the client storage (I can imagine it is stored inside the localStorage or in a cookie).
Of course this does not really invalidate anything, and if the token is not deleted for some reason, it can still be used for authorization purposes.
Your only option, if you really need a single access token valid at a single time, is to store some information about it in a database, and check that storage every time you validate the token. You could, for instance, store the hash of the token (never store the real token for this reason, they have the same value of passwords once stored) with the username, but please note that this approach makes your authorization protocol a little less stateless than before.

How can I protect my WebAPI from abuse and avoid sharing API keys?

I have a Web API written in C# and hosted in Azure with Azure API Management (AAM) sitting in front of that API and throttling requests.
The clients that call the API will be javascript based and will be calling on behalf of anonymous end users. For example, the home page of a web site might call our API via javascript to present information to an end user without asking them to login.
AAM ensures that callers to the API have a valid API key. There is the potential for this key to be copied and abused though if someone grabs it from the publicly visible source.
Is it possible to use OAuth2 to obtain a JWT Access Token without human intervention and for this to be exposed on the client?
OAuth2 can issue expiring JSON Web Tokens which would lower the risk of token theft, but I'm struggling to get this going without any human intervention.
OAuth2 is mostly about end user initiated authorisation but IdentityServer3 seems to have a Hybrid approach. Could I use this Hybrid approach to get the remote web server to request a token by sending the API key from server to server first and then outputting the JWT in the web page for use by the client side script?
This would then hide the API key and only show a JWT that is of use for a few minutes.
AAM can integrate with OAuth2 and inspects JWT Access Tokens, but I don't think it understands this Hybrid flow (it may not need to as we won't be asking for user logins).
Or should I just give up and rate limit requests only?
If you can generate these hybrid JWT keys without user intervention then API Management can validate them and use one of the claims as a key for doing rate limiting. Normally rate limiting is done based on API Management subscription keys, but the new advanced rate limiting policies allow you rate limit based on any expression.
I'm not familiar with how the IdentityServer hybrid mode keys work, but usually if there is non-interactive login, then there is some kind of secret that needs to be protected. This is always a challenge when running code on the client.
The API Management HTTP API does have a method to regenerate keys. You could use this to implement your own token expiry mechanism to limit the impact of key theft.

Restful API: how to access the api securely?

I have just started reading on implementing RESTful web services and creating RESTful apis. I have understood the basic concept of REST but I have been scratching my head a bit on how I will implement it securely?
Say for example, my webapp has a user login process. After successfully logging in, what else should I pass in the RESTful request to authenticate on server???
What I can think of is the following process:
user logs in (POST username/password to API)
API responds with a userkey
userkey is stored locally
When making any further requests, I include this key in request be authenticated
But here it seems that userkey is a state which I am sending to API, but REST happens to be stateless. Also this is not too secure in case of sending GET requests.
Is OAUTH the solution to my dilemma? Or some other way? Can somebody guide me on this...
Thanks
UserKey, or better call it token, is a client-side state. Your RESTful API will remain stateless since it stores this token no where.
Usually this token is a combination of some segments (username, password, login date) hashed as MD5, SHA (or any other algorythm). Whenever client calls an operation of your RESTful API, your service will compare the incoming token with an on-the-fly generated one using the same segments. If both generated tokens are equal, request gets authenticated.
There's no problem with GET or POST methods: you'll need to retrieve your token from query string or an HTTP header.
The point to secure your connection is calling your RESTful API over SSL, so your communications will have a high degree of security.
An important problem with GET and sending this token using query strings is maybe it's too long and URL length limitations would prevent you from having a lot of arguments in addition to the token itself.
In my opinion, you should go with POST verb, because you can send more data, it's more flexible and you avoid giving problematic arguments in query string, which can be bad in terms of logging, since you're going to log user names, passwords, tokens and other things, which are sensitive information that can compromise your users if a hacker steals your logs (or some unwanted person checks your log too).
OAuth is stateless - it's a token that proves that someone has authorized a client to do something - like a drivers license where the government has authorized a citizen to drive around in a car on their streets.
So - yes - use OAuth.

Resources