Please could you please share with me your knowledge about keeping the user logged in until token expires?
The program flow looks like: browser - client (server that reaches out resources). Client is a confidential one so we are going to use authorization code that will be exchanged for a token and kept secured. As our browser has only auth code I think that it would be good to keep it with a little shorter expiry duration than the token in a cookie and till that time treat it as we are still logged. Once cookie expires rerun auth process again.
Server side will have a cache that maps the auth code to the token. Furthermore, cors will be set up to allow only send request from the host the static web app is hosted.
Is it a good approach?
Thanks in advance for any advice!
Related
I'm working on a web application that will be installed on-prem behind Azure App Proxy. I can authenticate with OAuth and access the app successfully, but the authentication token is only good for an hour, after which my application is kind of dead because none of its API calls make it through the proxy.
So I'd like a way to keep that access alive so that users don't have to re-authenticate every hour.
I know that there's a flow for exchanging a refresh token for a new access token, and I can do that. But it seems like the ability to pass through the proxy is not governed directly by that token, but by a cookie called AzureAppProxyAccessCookie. Since I don't know how to convert my refreshed access token to a valid cookie value, this doesn't seem to solve my problem.
Note that I don't manage the proxy, so just increasing the expiration time on the token issued by Azure isn't an option.
So is there a way to refresh the AzureAppProxyAccessCookie token, or otherwise keep the session alive without making the user re-authenticate?
You can define a token life time policy with a longer token lifetime and assign it to your application.
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-configurable-token-lifetimes#access-id-and-saml2-token-lifetime-policy-properties
https://learn.microsoft.com/en-us/azure/active-directory/develop/configure-token-lifetimes#create-a-policy-for-web-sign-in
As said in OAuth2 rfc6749
The implicit grant type is used to obtain access tokens (it does not
support the issuance of refresh tokens) and is optimized for public
clients known to operate a particular redirection URI. These clients
are typically implemented in a browser using a scripting language
Refresh tokens are not suitable for implicit grant.
My question is:
How a mobile app, will refresh the access_token once it expires?
How the big ones in the market are doing this? Which practices they follow?
I know it is not following security recomendations, but it´s a good practice to make an long-lived access_token in this case? It can get annoying to need to re-authenticate each 30 min you use an app, or you close and reopen it.
As necessary permissions don´t change, a silent log-in on every app start, will be a choice to consider?
You don't necessarily need a refresh token to allow continued usage once an access token expires. If you must insist your clients use the implicit flow, then they may be able to make use of cookies and redirects to keep getting short-lived tokens without user interaction. Providing your client apps are using an HTTP agent which can use permanent cookies. e.g. apps that run in a web browser.
The key then is keeping the user signed into the identity provider the first time the token is requested.
This is done for example by the Identity provider (you I guess?) creating an HTTP cookie for the user agent to persist. Most big identity providers will do this - i.e. keep you signed in.
Now, when the token expires your client app will send the user back through the Oauth process again but, because the user has remained logged in to the identity provider, the identity provider can authenticate the user from the cookie without prompting for credentials.
If your clients instigate this token renewal on a background thread they can request the token as normal and, through the magic of HTTP redirects and cookies, get back a new token from you with no user action required.
Again - this alternative to refresh tokens relies on the client device being able to utilise permanent cookies, and your users remaining signed in and your auth server handling http cookies. If your clients are using native apps this solution may not work.
As in the future you will have 100s of clients maybe your auth plaform should offer different auth flows to different clients.
This article on mobile apps and implicit flow may be of interest to you.
Native apps are supposed to use the Auth code grant. So you can use refresh tokens. There is an RFC that discusses reasons (mainly security) for that as well as platform specific details. There is an important implication - the /token endpoint of your OAuth2 provider should not require authentication for getting tokens, because your application cannot keep its client secret safe.
Watching this video, it details in OAuth2 that the client application first has to get the authorization grant from the Authorization server and then use that grant to get a token before being able to access the resource server. What purpose does the grant serve? Why not give the client the token right away after the user signs on with his/her username and password?
Because it is more secure, for some application types.
What you describe is so called authorization-code-flow. It is normally used for "classical" web applications, where only the backend needs to access resource server. The exchange of authorization code to access token happens on the backend and access token never leaves it. Exchange can be done only once and in addition client id and secret (stored on the backend) are necessary.
Single-Page-Applications often use implicit-flow where access token is delivered to the frontend directly in the URL.
See more here:
IdentityServer Flows
EDIT: Q: "I still don't see how it is more secure given that you have to have the grant in order to get the token. Why need 2 things instead of just 1 thing to access the resource? If someone steals the token, they can access the resource anyway – stackjlei"
"Stealing" access token will work independent on how your application acquires it. However, stealing access token on the backend is much more difficult than on the frontend.
Authorization code is delivered to the backend also over the frontend but the risk that someone intercepts and uses it is tiny:
It can be exchanged only once.
You need client-id and client-secret in order to exchange it. Client-secret is only available on the backend.
Normally, authorization code will be exchanged by your backend to access-token immediately. So the lifetime of it is just several seconds. It does not matter if someone gets hold of used authorization code afterwards.
In your scenario there could be two servers, an Authorization and a Resource one.
It could be only one as well, but let's imagine this scenario.
The purpose of the Authorization Server is to issue short lived access tokens to known clients. The clients identify themselves via their CLientID and CLientSecret.
The Authorization Server ( AS ) holds the list of clients and their secrets and first checks to make sure the passed values match its list. If they do, it issues a short lived token.
Then the client can talk to the Resource Server ( RS ), while the token is valid. Once the token expires, a new one can be requested or the expired one can be refreshed if that is allowed by the Authorization Server.
The whole point here is security, Normally, the access tokens are passed in the Authorization header of the request and that request needs to be over https to make sure that the data can't be stolen. If, somehow, someone gets hold of an access token, they can only use it until it expires, hence why the short life of the tokens is actually very important. That's why you don't issue one token which never expires.
You have different type of OAuth. On type doesn't require to use the 'grant' authorization. It depend who are the user/application, the ressource owner and the server API.
This way, you - as a user - don't send the password to the application. The application will only use the grant token to gain access to your ressources.
I think this tuto is a pretty good thing if you want more details
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
I've been reading abount using Passport for the authentication process in a MEAN stack web app. I've been following this tutorial, but I got confused when it comes to the refresh tokens.
I do understand that those tokens are used to get a new access token for the user once it has expired, as explained here and in any other OAuth tutorial about thos tokens, but what I don't understand is how the server knows which refresh token must be used if the user hasn't provide any credential (it is supposed to provide the credentials just the first time is logging in).
Can anyone help me with this to fully understand how this works?
Thanks a lot :)
The Authorization Server issues the first refresh token after the user has authenticated. It then stores the association between refresh token and user as part of server side state so that it knows which refresh token was issued, whether it is still valid and for which user.
When the Client comes back to the Authorization Server with the refresh token later, the server can lookup the context and associated user from the server side storage.
Well, finally it turned out that the tutorial I was following was wrong (at least on what it comes to the refresh tokens).
On the tutorial it said that Passport use the refresh tokens to send a request to the Auth Server to get a new access tokens. Well, that's not true. According to Jared Hanson, the author of Passport, Passport doesn't handle refresh tokens, that's something the backend of the applications have to handle if desired. Passport is just meant to make the first request to the Auth Server, when you get the access and refresh tokens. Then you can use refresh tokens to request new access tokens, for example using background tasks to check if any access token is going to expire anytime soon.
I think the one who wrote that tutorial was confused cause the second time you login with whatever strategy is available (Facebook, for example), the service doesn't ask for credentials, but that's not because of the refresh tokens, that's just cause the browser is saving the FB session. If you go to FB and logout, the next time you try to login in the app with FB, it will ask again for the credentials. In fact, if I'm not wrong, access and refresh tokens should be removed once a user logs out. Kind of surprising that you could find that kind of mistakes in a IBM developers blog.
BTW, Jared Hanson's comment about how Passport works (without using refresh tokens) can be found here. Since is an old issue, I asked him myself on Twitter and the answer was just the same :)
I am just getting started working with Google API and OAuth2. When the client authorizes my app I am given a "refresh token" and a short lived "access token". Now every time the access token expires, I can POST my refresh token to Google and they will give me a new access token.
My question is what is the purpose of the access token expiring? Why can't there just be a long lasting access token instead of the refresh token?
Also, does the refresh token expire?
See Using OAuth 2.0 to Access Google APIs for more info on Google OAuth2 workflow.
This is very much implementation specific, but the general idea is to allow providers to issue short term access tokens with long term refresh tokens. Why?
Many providers support bearer tokens which are very weak security-wise. By making them short-lived and requiring refresh, they limit the time an attacker can abuse a stolen token.
Large scale deployment don't want to perform a database lookup every API call, so instead they issue self-encoded access token which can be verified by decryption. However, this also means there is no way to revoke these tokens so they are issued for a short time and must be refreshed.
The refresh token requires client authentication which makes it stronger. Unlike the above access tokens, it is usually implemented with a database lookup.
A couple of scenarios might help illustrate the purpose of access and refresh tokens and the engineering trade-offs in designing an oauth2 (or any other auth) system:
Web app scenario
In the web app scenario you have a couple of options:
if you have your own session management, store both the access_token and refresh_token against your session id in session state on your session state service. When a page is requested by the user that requires you to access the resource use the access_token and if the access_token has expired use the refresh_token to get the new one.
Let's imagine that someone manages to hijack your session. The only thing that is possible is to request your pages.
if you don't have session management, put the access_token in a cookie and use that as a session. Then, whenever the user requests pages from your web server send up the access_token. Your app server could refresh the access_token if need be.
Comparing 1 and 2:
In 1, access_token and refresh_token only travel over the wire on the way between the authorzation server (google in your case) and your app server. This would be done on a secure channel. A hacker could hijack the session but they would only be able to interact with your web app. In 2, the hacker could take the access_token away and form their own requests to the resources that the user has granted access to. Even if the hacker gets a hold of the access_token they will only have a short window in which they can access the resources.
Either way the refresh_token and clientid/secret are only known to the server making it impossible from the web browser to obtain long term access.
Let's imagine you are implementing oauth2 and set a long timeout on the access token:
In 1) There's not much difference here between a short and long access token since it's hidden in the app server. In 2) someone could get the access_token in the browser and then use it to directly access the user's resources for a long time.
Mobile scenario
On the mobile, there are a couple of scenarios that I know of:
Store clientid/secret on the device and have the device orchestrate obtaining access to the user's resources.
Use a backend app server to hold the clientid/secret and have it do the orchestration. Use the access_token as a kind of session key and pass it between the client and the app server.
Comparing 1 and 2
In 1) Once you have clientid/secret on the device they aren't secret any more. Anyone can decompile and then start acting as though they are you, with the permission of the user of course. The access_token and refresh_token are also in memory and could be accessed on a compromised device which means someone could act as your app without the user giving their credentials. In this scenario the length of the access_token makes no difference to the hackability since refresh_token is in the same place as access_token. In 2) the clientid/secret nor the refresh token are compromised. Here the length of the access_token expiry determines how long a hacker could access the users resources, should they get hold of it.
Expiry lengths
Here it depends upon what you're securing with your auth system as to how long your access_token expiry should be. If it's something particularly valuable to the user it should be short. Something less valuable, it can be longer.
Some people like google don't expire the refresh_token. Some like stackflow do. The decision on the expiry is a trade-off between user ease and security. The length of the refresh token is related to the user return length, i.e. set the refresh to how often the user returns to your app. If the refresh token doesn't expire the only way they are revoked is with an explicit revoke. Normally, a log on wouldn't revoke.
Hope that rather length post is useful.
In addition to the other responses:
Once obtained, Access Tokens are typically sent along with every request from Clients to protected Resource Servers. This induce a risk for access token stealing and replay (assuming of course that access tokens are of type "Bearer" (as defined in the initial RFC6750).
Examples of those risks, in real life:
Resource Servers generally are distributed application servers and typically have lower security levels compared to Authorization Servers (lower SSL/TLS config, less hardening, etc.). Authorization Servers on the other hand are usually considered as critical Security infrastructure and are subject to more severe hardening.
Access Tokens may show up in HTTP traces, logs, etc. that are collected legitimately for diagnostic purposes on the Resource Servers or clients. Those traces can be exchanged over public or semi-public places (bug tracers, service-desk, etc.).
Backend RS applications can be outsourced to more or less trustworthy third-parties.
The Refresh Token, on the other hand, is typically transmitted only twice over the wires, and always between the client and the Authorization Server: once when obtained by client, and once when used by client during refresh (effectively "expiring" the previous refresh token). This is a drastically limited opportunity for interception and replay.
Last thought, Refresh Tokens offer very little protection, if any, against compromised clients.
It is essentially a security measure. If your app is compromised, the attacker will only have access to the short-lived access token and no way to generate a new one.
Refresh tokens also expire but they are supposed to live much longer than the access token.
I've written a little about this because I was pondering the reasoning myself today.
https://blog.mukunda.com/cat/2023/refreshing-access-tokens.txt
Essentially, I think the main security boost is only there if the refresh token does not remain the same over its lifetime.
Let's say someone steals your tokens from your browser cookies because they had access to your device temporarily.
If they use the refresh token, and the refresh token changes, then you have feedback – you are logged out. That can seem rightfully suspicious to careful users who can then take action and revoke all tokens.
If the refresh token doesn't update upon each use, then it is harder to notice that someone has access in tandem. (Chances are, if does update, then it might update from your device automatically before the attacker can even get to use it.)
If the refresh token does not get updated each time you use it, then I don't see any boost in security from the strategy, since it will be right next to the access token and client secrets.
So, why access tokens? It is so you can check that your credentials are valid regularly.
Do refresh tokens expire? Yes, but usually after a few months if you have "remember me" ticked. There's no expiration time in the spec, so you just go until it fails. Services that require longer unmonitored sessions might have secret credentials so they can refresh their refresh token.
Update:
I also glossed through the OAuth 2.0 specification and see the same reasoning, though it emphasizes that the invalid authentication feedback can be caught on the server side. That is a great point – the server can automate revoking the token if it is compromised.
If a refresh token is compromised and subsequently used by both the attacker and the legitimate client, one of them will present an invalidated refresh token, which will inform the authorization server of the breach.