Stress-testing with artillery - Getting an auth0 bearer token using login flow - auth0

I want to use artillery.io as a stress-testing tool, and want to setup a basic stress-test. But all my url's are behind an auth wall (using Auth0) and I want to try to get a valid token for the testing session so that my backend does not throw me into a 401-spiral. The artillery docs explains that I can hook up to some lifecycle events using processor, but does not explain which lifecycle hooks I have available. I've managed to figure out that there is a beforeRequest hook I can use, but this does not seem optimal as this will probably run before every request. My tokens have at least an hour validity...
So the main question is; how do I construct a processor hook which taps into the auth0 login flow, retreives a token which can then be stored in an environment variable (or some other local mechanism) for use as an Authorization Bearer token in future requests done by artillery?
OR if this is a bad pattern to follow, what is the best practice for urls behind auth-walls? I've already thought about loging in first and then copying the token to an environment variable and use that, but this makes the test a bit harder to use since it requires a manual step.
Any input is greatly appreciated.

Related

Is it bad practise to automatically use the refresh token in an interval?

As I am working on implementing a proper auth flow into a react web app, I am presented with different patterns of how to use access and refresh tokens.
I am considering the following two patterns:
Creating some sort of middleware to the fetch API:
This middleware runs before every request to the backend and checks whether the access token is still valid or not.
If it is invalid, it first calls the auth server to fetch a new access (and refresh) token.
Creating an interval which is independent from all other logic to keep the access token alive.
Say if the access token is valid for 5 minutes, the interval will run every 5 minutes to fetch a new access token
I would also make sure it only runs every five minutes, if the user is still active , so that the application left open without any user interaction for a long time will automatically log out
Any API call simply uses the currently active access token and does not need to worry about checking the token first or anything
The second approach seems much much easier and cleaner to implement for me, since it does not add any complexity to fetching data and is completely independent/seperate to the app otherwise.
I've been having a hard time to research this question though tbh. I'm not sure if there is some security issue I'm missing with that approach.
So my questions are:
Is there any security issue with fetching a new access token in an interval from the clients side?
Is there a common practise on how SPA apps (like the react app I mentioned) handle access tokens?
If yes, what is that common practise?
If there is no security issue, are there other cons of the second approach that I am missing out on?
Thank you for your answers in advance!
I think the answer depends, if you always do it every X minutes, and you have many active clients, it might create more load on the backend, compared do doing it on a need basis. Perhaps all clients are not so active all the time?
One thing to look out for is to make sure you don't trigger multiple requests at the same time to request new refresh tokens. If you get a race condition here, then you might be logged out (if you use one-time refresh tokens)
Also it is worth considering to use the BFF pattern, do watch this video
Using the BFF pattern to secure SPA and Blazor Applications - Dominick Baier - NDC Oslo 2021

Difference between iron-session and next-auth?

Why would one use iron-session instead of next-auth? Doesn't next-auth do normal username/password log-in in addition to Social (while iron-session only does the former)?
next-auth does a lot of things like you said but it also makes you do things their way. So you have to model your database a certain way to make next-auth work but it does come with a lot of helper functions and makes you write a lot less code.
iron-session only does session management. You have to write all the auth logic with iron-session which next-auth handles for you automatically.
As far as which one is better: if you'd like complete control over your database then use iron-session because sometimes next-auth might not work and it's annoying. I faced an issue with it so ditched it but it just might work for you. iron-session gives full control but you have to write the correct code. Personally, I'm facing issues with iron-session as well with useUser hook because I have to use react-query and not swr but it's probably my issue.
iron-session is lightweight library. It is simply used for session management. session is not related only to authentication. For example, maybe you want to sign some data on one API endpoint, attached the signed data to the req.session and you still need to reach this data on a different API endpoint iron-session store data on the encrypted cookie and save it to the browser. From here:
Node.js stateless session utility using signed and encrypted cookies
to store data. Works with Next.js, Express, and Node.js HTTP servers.
The session data is stored in encrypted cookies ("seals"). And only
your server can decode the session data. There are no session ids,
making iron sessions "stateless" from the server point of view.
On the other hand, next-auth is a more robust authentication package. as the name says next-auth, it is dedicated to authentication. It has too many authentication methods. It creates a session specifically for the user's login

How to block user with immediate effect in auth0

I tried auth0 and I face a problem where I can't block or force logout a user.
After i blocked a user from auth0 console, The user who was logged in could still access the routes.
I used express-openid-connect middleware and requiresAuth()
I suppose this is a common problem with JWT based service ? and should I implement a statefull session to manage user for these kind of use cases ?
In JWT based services it’s common practice to make the access token lifetime a short one, e.g. 10-15 minutes. That way user can still access the api inside a short window but soon the token needs to be refreshed. And when token refresh takes place the authentication service gets called and can reject granting a new token.
So you can make sure your access token lifetime is short enough and that should be enough to satisfy the security requirements.
It’s of course technically possible that you implement stateful session to check user info on each request but you should not call Auth0 api in this case cause you are going to hit their rate limiter and it slows down your api requests. Some sort of sync to your server side fast read database/cache would be needed.

Vue + Overmindjs -> Creating Interceptor for GraphQL requests

I'm using Vue with OvermindJS (instead of Vuex) for state management. Within Overmind, I use GraphQL following this tutorial from their official docs. It works like a charm, but I run into a problem with the authentication. I use a JWT approach with a refresh-cookie. That means I need to refresh the Token at certain intervals or when it's expired.
I think an interceptor that can check if the token is expired every time I make a request to my GraphQL endpoint would be the best approach. Is this possible in Overmind? Alternatively, I could create a Promise function to every created request that checks it, but I don't find that solution particularly appealing.
Cheers

Auth0: Specific questions about token storage and flow for mobile app

I’m building a react native app that will interact with APIs that I also write/manage. I have found Auth0 documentation for implementing this flow, but I’m not sure on where/when to save the tokens. I want to be sure I nail this step, because I feel like it has the potential to reduce the security of the flow by a great deal if I don’t do it correctly.
Here is the flow as I understand it (no error handling, only happy-path for sake of brevity):
A user enters the app for the first time, or is not already logged in
They log in using the Auth0 web-login-thingy
I receive a token
I can use the token to authenticate with my API
Questions:
Do I store that token? I don’t want my users to have to log in every time they use the app. If I do store the token, where do I store it?
If I’m not storing it, what do I do? Do I ping an authentication/authorization endpoint with Auth0 every time they open the app and get a new token?
Say I am storing the tokens, if I'm using the ID token for user data, should I be hitting the API again regularly to keep it up to date? Only when the user opens the app again? Not until they trigger a change in the app?
Instead of using the ID token for user data, should I just use that to get the user's ID and ping my database for user data?
I have the basics of this flow, and I'm able to sandbox it, but I want to start applying production-ready app logic to this flow and that's where I'm stuck. I’m a little lost here, so any help is good help.
Thanks!!
Here's a brief answer to your questions when using Auth0:
Yes! you store it, the most secure way to store the token is in your device's local storage, that way it is not kept either in application's state or in a global variable.
2&3. See above, but to add more information, you can configure your tokens to have an expiry length. in theory you would convert this 'expiry time from inception' to a date object, and can do one of two things; you can request a new token using the Refresh Token (that comes with the original) once the expiry has been reached, or force the user to re-log in and re issue a new token at this time (i prefer the latter, prevents people from just renewing their tokens forever as long as they remain logged in)
Use the auth token to request user information after login, this can be stored in app state/global variables/wherever. You then want to use the auth token in the Authorization Header for each API call, along with whatever data you are sending. this ensures that even once someone is INSIDE the application, they need to have a valid token to actually do anything involving data (imagine someone back-dooring into your app and skipping the authorization, or using something like postman to just hammer your API with garbage). it would work something like this: GET userData { Header: auth token } -> GET userProfile (by sending your user ID returned from GET userData) PLUS {Header: auth token }
I can give more in depth examples if you wish, and i apologize if i misunderstood any of the question and gave redundant/incorrect answers
Edit: Resources about using secure storage for keys
Document for when to use in-memory storage Vs persistent storage. The TL;DR is use in-memory if the key is expected to expire before a standard session duration, and persistent for storing a key between sessions
https://hackernoon.com/mobile-api-security-techniques-682a5da4fe10
link to Keychain Services doc
https://developer.apple.com/documentation/security/keychain_services#//apple_ref/doc/uid/TP30000897-CH203-TP1
link to SharedPreferences doc
https://developer.android.com/reference/android/content/SharedPreferences.html
AsyncStorage is a simple, unencrypted, asynchronous, persistent,
key-value storage system that is global to the app. [1]
You could store it in your AsyncStorage, but thats not necessarily a secure location itself (e.g. not encrypted, accessible on rooted devices...). Typically clients will issue access tokens that last anywhere from several hours to a couple days and these will provide their owner access to your API-resources. If there is sensitive data behind your login screen, you're probably better off simply re-doing the auth-flow and invalidate older access tokens on login.