In my Node.js application I use OpenStack Swift (Object Storage) as a storage service. The app needs a authorization token to access the storage service, the (small) problem is the access token needs to be refreshed once in a couple of hours.
How should I do it to provide smooth experience to end client?
Refresh the token when expired in a reaction to OpenStack 401 response code.
Schedule the token refresh request manually via some sort of node scheduler or cron task.
The app relies heavy on access to storage service.
Using option 1 will effectively limit the access to app for my clients for a second.
This may seem nothing but if you multiply this by the number of clients its not so small.
If the application relies on some database/storage that requires authorization What is the industry standard for performing such server-to-server authorization requests?
For some reason obtaining token from OpenStack Keyrock takes a lot of time (~1s) that's why I'm asking.
NOTE: currently I'm not in a position to influence tokens lifetime.
Considering that you do not have the ability to change auth token lifetimes and are looking to hide the authorization refresh from users, it would seem only appropriate to go with your second option. Fortunately, timed asynchronous actions are easily implemented in Node.js.
It seems best to have this to have this update service rely on either the timeout threshold or expiration timing. Defining arbitrary timings doesn't seem optimal.
Related
I have an application, in which I have to fetch a list of users. The API to fetch the list requires an authentication token, which expires every 1 hour. So, in order to fetch the users, I first need to make a token call and post that I need to make the fetch call. How can I cache the token which is valid for 1 hour in Node? We have multiple pods, so I need a distributed cache to make sure that the token value is the same across the pods. Will it be possible to implement it in node and how to implement it? Any kind of resources/tutorials would be really helpful.
So you're calling an external service, but you need a valid token that you have to obtain first.
Take a look at how existing software tackles it. For example, Microsoft's Graph API SDK (which also uses bearer token auth):
https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md
You inject an "authentication provider" that authenticates and retrieves a token from the remote service when necessary. Next, when you need to make a call to the API, the client checks if it has a token in-memory. If it doesn't (or if it's expired), it asks the authentication provider for a new token. So, the in-memory cache layer is in the client object.
Another approach is in-memory caching, but in the Authentication Provider layer - then, the client can blindly ask it for a token every time, and let the Provider decide whether to use the current token or ask for a new one.
I would refrain from putting the token on a network-accessible cache - it opens up a potential security hole for leaking the token, and does not seem to serve any purpose.
I am completely new to O-Auth but I have just implemented my first O-Auth flow in obtaining access tokens from an external API to gather information on users using NodeJS and Express. The external API generates an access token and a refresh token as the access token only lasts for 24 hours.
I am wondering what is the best practice to store API access and refresh tokens as I will have to use them even when the user is not accessing my application to gather information in the background. Would it be just a database and then querying the database on the server side of my application to access the API? Then refreshing the token and updating the entry from within the database?
Any advice is welcome!
The answer really depends on the type of API client you are using. OAuth has standard solutions for the below 3 scenarios. As a next step, maybe let us know which of these scenarios is closest to yours:
Web UI: gets tokens for an end user, stores then in memory, can deal with access token renewal via cookies
Mobile UI: gets tokens for an end user, can store them in OS specific secure storage
Back end process: gets tokens on behalf of itself, stores then in memory and re-authenticates when tokens expire
I would aim to leave token storage to the Authorization Server, which has built in processes to do this in a secure manner.
Risks with a second token store are that a rogue employee could perhaps grab tokens and operate as users - so it is worth thinking about this kind of threat.
I am in the midst of designing a single auth model that works for both SPA+API server and web applications.
Got some insight from the here link to use access/id token in cookie form (none httpOnly) for web application integration.
Attempting the OIDC public client and PKCE way, the integration is workable for SPA+API server but I am stuck at the token
renewal flow for the traditional web application. Oidc silence renewal flow is pretty front channel initiated and when the access token is expired, what will be the options for web application to retrieve the new access token ? (assuming the session from IdP is not expired)
You should use the OpenID Connect hybrid flow. This will issue tokens to your front-end and traditional back-end Web app. It will also allow you to issue different kinds of tokens with different claims to each.
More specifically, the front-end may only get:
An ID token; or
An ID token and access token; or
An ID token and access token and a refresh token.
Also, the back-end may only be issued any combination of these.
You can test the hybrid flow if you're unfamiliar with it using oauth.tools.
For the front-end, you have a couple option to continue access the protected resources without prompting the user:
Rely on SSO (the front-channel approach you mention) or
Issue the SPA a refresh token
In the refresh case, take note of the best common practice for this:
The refresh token should be created anew whenever it's redeemed
Refresh tokens must expire by a certain time or after a certain period of inactivity
Renewed refresh tokens must not be renewed beyond the lifetime of the original
If you do these things, there's still risk involved in issuing an SPA a refresh token, so consider:
Not issuing one or
Doing a combo of the two approaches
When doing a combination (SSO + RT), you could cap the lifetime of the refresh token to something that shouldn't greatly impact the user's interaction with the API while still requiring them to prove control of the original credential with some amount of frequency that offsets the risk. In such a case, the friction of having to login could be lessed by allowing SSO at the authorization server. This too introduces risk, so its lifetime should be limited.
I would look at all these timeouts as knobs that you can turn and twist to ensure an adequate amount of security.
Extending the period of access for the traditional, back-end application can be done using the same two options (SSO or RT).
In order to access resources in Azure AD web applications we retrieve an authorization code using the following workflow:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Now my questions is, does this retrieved code also have a specific lifetime (like tokens have) or will it never expire? I guess it won't expire but I need to be sure about that.
Yes, the authorization code has a lifetime of 10 minutes I think.
You use it to get the tokens you need and then throw it away.
You'll get refresh tokens so you can use them to get more tokens later.
ADAL.NET for example handles the token refresh for you, assuming you properly implement a token cache.
Reference: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-id-and-access-tokens (scroll all the way down) (it's for the v2.0 endpoint, but codes are similarly short-lived in v1)
Authorization codes (work or school accounts)
10 minutes
Authorization codes are purposely short-lived, and should be immediately redeemed for access tokens and refresh tokens when the tokens are received.
I am building an Authorization Server in terms of OAuth 2.0.
There is also a 3rd party web application (Client) which is using my Authorization Server. It's a regular web application, and the user may have several active sessions established with this application (for example, office and home machine, or just several web browsers on the same machine).
My Authorization Server issues an access token #1 (with or without the refresh token, that's not so important here) for Client once. When the user starts a new session with the Client, should the Authorization Server give the Client app the same access token #1 for that new session or should it issue a new #2 token?
My thougts:
From security point of view the new token might sound better, but then if the user wants to manage his authorizations, he will see a separate entry for each Client session, which might be messy.
For example, GitHub returns the same token for previously authorized clients, and on the "applications" page in my GitHub account I see only one entry per application, no matter how many sessions I've started, which is convenient.
However, this approach means that I have to store access tokens in Authorization or Resource server in the reversible way (plain-text or encrypted with some known key) instead of using irreversible hashing (like you usually do with passwords, storing salt and password hash from bcrypt, pbkdf2 or something similar).
Please be advised that I am not a security expert and this explanation
is my general idea of oauth. Reason why I mentioned this in the
beginning is because I see you are CREATING YOUR OWN AUTH SERVER based
on oauth 2.0 protocol, which means down the road some people might be
using your server for authentication, and thus I don't want you to
have the wrong concept.
The session-oauth mismatch
I want to clear this first that don't mix sessions and oauth. These are two separate things usually found working together IMHO.
Oauth protocol simply gives the apps/users with an access token via which the app/user can query your server for data associated with the token.
Session on the other hand depends on the application itself. Once some app received the token, they make a session out of it. When user logs in or logs out, the session is destroyed, not the oauth.
So what is the fate of oauth token?
Well from a server standpoint, each of your token should expire after a certain time period. That is it. Server does not know anything else. It gives you the token, then expires it after 'n' seconds.
However, the app may decide that it wants to revoke the access token. Maybe their website was hacked, or maybe they are done with all api calls. Then they can send a special request to your server telling you to force-expire the token.
So what should I do about user opening multiple sessions?
ABSOLUTELY NOTHING. As an oauth service provider, you are not concerned with sessions at all. All you know is that if the app asks you for a token, you give them one.
However, I will answer you question about sessions as well. Should you spawn different sessions for the same user? I would say yes. If you have same session, then if you log out from one machine, and refresh the page in second machine, since the session has expired, your other browser/machines will also log out naturally.
So how does github manages to not show extra entries?
Well I do not work for them so I don't know. But I guess that they will check each session, and if two or more sessions are associate with the same user, they know the user must be using many devices. Then when one of your devices sends some request to github, they can guess from the IP address your location, and if many of your machines are making requests from same place, you got to be using multiple machines. If not, then maybe some attacker is using your account as well.
This is how AFAIK banks predict malicious users - well not the only way, they sometimes also predict the pattern you are using to access bank records, and if that pattern is different, there are good chances that your account was compromised.
So now you may ask me, are you really sure that I should create as many tokens as the app demands me?
This is the part where I am not so sure. From what I have seen, oauth has two things. Google these two terms for more info:
Refresh Token: This token is not your access token. This token never expires, and once your access token is expired, you can use this token to get a new access token. This token is also to be kept secret.
Offline access type: Many oauth providers such as google and facebook also support this mode. This mode basically allows you to extend the expiry time of your access token. E.g. instead of normal expiry time of access token (e.g. 1 hour), for offline tokens you might have the expiry time of 1 year or so.
Answer to the question "Should I reuse OAuth 2.0 access tokens?"
Yes, the token is supposed to be used as many times as you need within the given expiry time (google sets it to 1 hour).
After it has expired, use the refresh token to get another access token and use it as many times as you need. Keep repeating the process.
If your users won't be online for you to start the oauth process, and you don't have the refresh token, then the app needs to have "offline" tokens.
Should I store my auth tokens?
You can if your app demands it, but it is nowhere recommended because of the potential to be leaked. Tokens are supposed to extract data within the given time limit and reissue the token when needed again. However, you surely can store them if you want.
"Offline" tokens, on the other hand, are expected to be stored. You can encrypt them if you like, but if the scopes are not too broad, I wouldn't bother at all.