Handling JWT token renewal within Apache Camel - apache-camel

I've recently been working on setting up a project to use Azure and part of that involves requesting a token to access a REST API. I've been told that the token will expire in 30 minutes, but calling the API to get a new token isn't particularly expensive. I can do all this without any issue, but I'm curious if Camel has anything built in that can handle this for me without having to explicitly call to get a new token?

I don't know of anything built in, but you could have a timer route that runs every 25 minutes that requests a token and puts it in some kind of global state.
from("timer:getAuthToken?period=1500000")
.to("http:myKeyServer/getKey")
.process(new MyKeyProcessor()) // store in global state, static, spring, etc.
Then any route that needs the key can get it from global state and set it in a header or exchange property.

Related

Gatling Java REST API Automation: how to implement API call with Auth that expires (hence token has to be regenerated after every hour or so)

So I am able to do this fairly easily in JMeter, I wanted to try out if I can do this with Gatling.
(Note: I am using Gatling Java DSL and JDK 1.8, not planning to use higher version java.)
Problem:
Auth Token API Call --> generates a token expiring in 50min (this cannot be changed)
Call REST API with this token
Do Reauth (step1) if API throws 403
My flow: (made some progress on this)
Call Auth API --> save token to session
(Checking if status is 403 or when script is initializing (status is not in session) --> only then generate new token)
Reuse the same threads (users) to call APIs. (looping users)
No need of creating new thread/users every time. Since we will store the http.response.status on the session, we will use the same users for identifying when to do reauth. If you create new thread/users every time, their session data will be clean when they complete and the 403 will not be propagated to do reauth.
Call REST API --> save http.response.status on session --> if response is 403 (this should cause reauth) --> loop back to step1
Is there a better way to implement this. I am not able to identify a cleaner solution. Also a little stuck at the last part, just created a rudimentary POC. I can share my code if you need reference.
I assumed this would be a very common problem with REST API Testing, since the authentication tokens are always with some expiry. But I dont see any obvious/easy solution.
Thanks for your help.
It seems you want to completely bypass per virtual user authentication. If so, you could have 2 scenarios:
one that would periodically take care of preemptively fetching an auth token (meaning the loop period is less than the token max age) and store it in a global variable.
your real scenario that would use the current global auth token. Just make sure to delay the injection profile (nothingFor) so the first scenario has time to fetch the first token.
Based on Stephane's response, I have come up with the following solution:
The java file can be found here.
GitHub link
Created 2 scenarios.
Calls to /authorize endpoint and saves the token to a static variable
Calls to /order endpoint with the authorize header updated with token
The images below show requests, and the order of calls based on the load profile.
/authorize then 4 /order calls --> first auth header
/authorize then 4 /order calls --> updated second auth header
Image1: Shows first 4 calls having Authenticate: Bearer 202212363211618239
Image2: Shows second set of 4 calls having Authenticate: Bearer 202212363211718325

What is the best way to store an admin API token in Next.js ? Feel like storing it client side as http only cookie is risky

I'm working on a e-commerce using next.js and sylius API and the API admin routes are secured using JWT. So in order to fetch products (for example), i need to login to the API, get the token and then fetch the products using the token. The most common method to be able to send the token on every new requests to the API is to store it in a HTTP-only cookie.
As the pages are generated statically, i feel i don't need (and want) to expose the API token to the client. So i'm wondering the best way to store the token ?
Here the different options i have in mind right now:
store the token as a http only cookie and use it server side (with a proxy using next js API pages) in order to call the sylius API. Like i said, i'm not confortable to store the API token into the client, it seems risky to me, as it will be exposed to everyone, and with that token you can access the admin API.
configure the API in order to prevent the token from expiring, and store it in the next js app as an environnement variable (.env.local), so that it's not exposed to the client and can be used for fetching the api when generating static pages. The official ecommerce theme of Next.Js seems to use that method (https://github.com/vercel/commerce/blob/f770ad7a91059a2ecfbb9de1bac111dfe7016124/framework/bigcommerce/api/index.ts#L82)
store the token somewhere in the next js structure but not as an environnement variable (maybe a config file?), so that it can be replaced if necessary (if the token expires etc).
get the token and store it in the react state as is it will be used once only for generating all static pages. On each build the token will be asked again by the API and then used for fetching the API for exporting the static pages with the content. It don't need to be saved more time than the building step.
For me the last option seems better but i feel i'm missing something there, i'm kinda new to next, so i'm not sure exactly if its a good solution.
Thanks :)
I get a great answer from a reddit user ("supermaguireray"), so i post it as an answer here:
"First of all, in any session management mechanism the correct information needs to live on the correct domains, what I mean is that your client can only have access to a identification information, but never to data used in the server, these can be applied to a server-side session, when a ID for the user data stored on the server is sent to the client (preferably encrypted), or in a JWT where a encrypted string is sent to the client (identification), and decrypted on the server (Data).
With that said, the only reason you should send the API token to the client is if you need to fetch data directly from a browser. Storing as a httpOnly cookie is the most secure way.
In case you only need the cookie fetch data to the next backend, to render your SSG or ISR pages, there is no need to send a cookie to the client. Just store the token in your server. I would store it as env variable. Use next.config.js->runtime-configuration.
Or, you can keep a expiration date for the token, and store the credentials, maybe even in a DynamoDB or FaunaDB app."

Best practices for refreshing JWT in SPA?

Hi I'm developing a React app that communicates with an Express API. I'm trying to implement JWT authentication but I don't know what should happen when the jwt expires. It not seems very user friendly if the user is logged out when the token expires.
Should I use refresh tokens? As it says in the node-jsonwebtoken package documentation (jsonwebtoken). This may not be the best approach.
Should I create a new jwt in every request to the server? If the user reads an article for a long time without doing any request, he is going to be logged out.
Maybe I'm wrong and the best practice is using a big expiration time and let the user be logged out. If this is the case what would be a reasonable time?
Thanks!
A pattern commonly used along with refresh tokens is to follow a workflow along the lines of:
Some API call / resource returns with a 401, alerting that the token has expired, this sometimes is accompanied by a reason, e.g. Expired token, invalid token
Create a reference to the API call that failed, to retry later
Attempt to refresh the token with the refresh_token
If the refresh works, go ahead and perform the queued API call again
If the refresh fails, the user will need to log in again
You can also use the above approach to queue multiple failed requests, in the event that multiple calls fails whilst a refresh is taking place.
Coupled with a decent expiry time, which really depends on your application, this has proven to be a robust solution in the past for me.
An alternative approach would be to implement a 'heartbeat' API call that updates the user's token periodically whilst they are on the site, however this may come with side effects that may not be desired.

Oauth2. Asynchronous refresh_token calls

We have a client which communicates with a server secured by OAuth2.
As implementing tokens flow we have faced a problem. When page loads, there are few components that make calls to different secured endpoints.
There is a situation when access token is expired so all requests get error and try to refresh it. So we have few asynchronous requests.
Is there an approach to deal with such situation?
Our client is written on React JS.
There are a number of solutions to this.
One solution would be to create something like a TokenService.
Before you fire any http call, you work with this service and check if you have a valid token. This is easy since when you create the token you get back information on how long the token is valid for. You store that somewhere and before you fire a call you check if you are still in the validity window. If you are then you fire the http call, if you are not then you request another and update the stored one with the new one. Once this is done then you fire your http call with the valid token.
If you don't want to manage this complexity then you could simply request a new token for every request and you're done. You use each token for one call and that's it really.
You could also use the refresh tokens functionality if you have that implemented, so if your token expires, you simply refresh it and move on

Refreshing JWT in Express.js

I'm using JWT for authentication in my Angular.js application, with Express.js on the server side.
Basically, when user logs in, a new token is created (using https://github.com/auth0/node-jsonwebtoken) and send back to the client. If token is valid also on the client side (angular.js part, using https://github.com/auth0/angular-jwt), a new user is created and the token gets stored in a cookie.
So, each request to certain path on the server is protected by a token validation. However, my token has an expiration time. Now let's say for the sake of argument that expiration time is 30 seconds; user can actively use my application for 30 seconds and after that, he gets logged out. That's not exactly user friendly.
So what I did was that with each request to the server, I create a NEW token and send it back in the head of response. When I receive the response in my Angular.js client-side, I read the token and overwrite the token in the cookie. That way, as long as client is active (or rather, makes requests to the server side), the token gets refreshed.
Now I'd like to know the following:
Is such an approach correct? The downside is, that token gets created at each request and send back in each head of response. Cookies get overwritten quite often (performance issues?)
What would be the correct approach?
Is it OK that the token expires if there are no requests to the server? Client might still be using the application, however, if he's only writing on client side something (or reading), the token does not get refreshed.
Thanks for your time and responses!
Yes, that is a valid approach. It is the same approach many take,
including the popular Angular module ng-token-auth. You might
consider saving the tokens to local storage, with a fall back to
cookie storage if the browser doesn't support it (see
http://caniuse.com/#feat=namevalue-storage for coverage).
I would do what you describe.
One solution is to use $interval to basically ping the API. All you need to do is send in a token a get a new one back (i.e., in headers like you are now). Keep track of how many "pings" you've sent. You can reset the number of "pings" upon certain actions like on ui-router's $stateChangeSuccess (i.e., navigating to a new view) or anything you like, including submitting a form or other non-ping requests. When the number of "pings" reaches your threshold, warn the user that their session is expiring, and after a delay, erase the stored token and log them out. Check your ping responses for authentication errors from the API, indicating that the user might need to be logged out and/or redirected.
Perhaps you just gave 30 seconds as an example token lifespan. I would recommend getting closer to the browsing session timeout that you want. As points of reference, consider that the Ruby gem devise_token_auth defaults to 2 weeks and that .NET defaults to 10 hours. Your needs may vary.
The problem is also addressed by using refresh tokens. Your access token has a short life and is verified by signature. The refresh token has a longer life and is used to get new access tokens.
When the refresh token is used to get a new access token, that is a good time to do extra checks: has the refresh token been revoked? Is this user account still valid?
Both tokens can be stored in secure cookies and supplied on every request. Doing this allows your server to transparently use the refresh token when needed and set new access tokens in cookie responses.
This is the approach we've taken for Express-Stormpath and is documented in our Authentication section of the documentation. If you'd like to offload your authentication layer, I'd suggest Stormpath. (Disclaimer: I work there, and wrote that module).

Resources