We are using Azure AD authentication with a bootstrap MVC site.
Everything is fine and dandy - except we have an issue with the token timeout.
I have read multiple articles about the token lasting 1 hour before re-authenticating against Microsoft.
Our problem comes up when posting data.
Efter we enter a page with a post form on it - and this hours expires when on the page - the post data gets lost when posting the data. Everything points in the direction of the problem occurring when the site goes to get a fresh 1-hour token.
Has anyone here had experience with this or have any idea of how to get around this problem?
Not sure if this is the right way of doing things, but this is how we're handling this situation.
Basically when a user authenticates against Azure AD, you get 3 things back - Access Token (which expires after 60 minutes), Refresh Token and Token Expiry. What we do in our application is cache these three items.
Whenever we perform something that requires Access Token, we first check if the token has expired or not (by comparing the server date/time with the token expiry). If the token is not expired, we simply use that access token. However if the token is expired, we fetch new tokens using refresh token (fetching new tokens using refresh token will again return Access Token, Refresh Token and Token Expiry which we cache again in our application).
Related
I have a multitenant web api project with microsoft azure integration. I connect to microsoft, get access token and refresh token and each time before access token expiration, I call api
POST https://login.microsoftonline.com/tenant/oauth2/v2.0/token
data in request is:
grant_type=refresh_token
refresh_token=xxxxxxxxxxx
client_id=xxxxxxxxxx
I get new access token and refresh token, and after an hour get new access token with the same api and last recieved refresh token. But after 24 hours somehow my refresh token expires, and I need to reconnect and enter my credentials again.
How to make my refresh token don't expire until i revoke it manually. I need somehow update refresh token timeout in background and save my integration always connected until i revoke it manually.
I need somehow organize this to stay connected always until manual revocation. Any solution?
There is a 24 hour limit to refresh tokens under certain conditions:
Refresh tokens sent to a redirect URI registered as spa expire after
24 hours. Additional refresh tokens acquired using the initial refresh
token carry over that expiration time, so apps must be prepared to
rerun the authorization code flow using an interactive authentication
to get a new refresh token every 24 hours. Users don't have to enter
their credentials and usually don't even see any related user
experience, just a reload of your application. The browser must visit
the log-in page in a top-level frame to show the login session. This
is due to privacy features in browsers that block third party cookies.
See: https://learn.microsoft.com/en-us/azure/active-directory/develop/refresh-tokens
Error:
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
However, another app I use, with a different account, never runs into any issues. I use the same Python OAuth Quickstart for both.
Token has been expired or revoked.
Basically means just that either the user has revoked your access or google has. Users can remove your access directly in their google account when ever they want to.
Google expired tokens
If you are using a gmail scope, and the user changes their password. Your refresh token will probably be revoked.
If your app is still in testing and the refresh token is more then seven days old the users consent will be removed and the refresh tokens will be revoked.
If the refresh token has not been used in more then six months the refresh token will be revoked.
If the user authroizes you app you get a refresh token, if the do it again you get another refresh token. both will work. You can have up to 50 outstanding refresh tokens for a user. If you request again then the first one will be expired. Ensure you are always storing the most recent refresh token.
no matter what the cause your application should be configured in a way as to request authorization from them again if the refresh token has expired.
On my localhost, I have authenticated my user and goten a Refresh Token and Access Token using Passportjs.
I am using Google's Official Node.js library to get the Google Analytics data and it all seems to work fine.
On this GitHub issue, Justin clearly mentions that the expiry is set by Google's APIs.
How long is the refresh_token valid and at what time do i have to authorize myself again?
This is more of an Oauth2 question then a Google Analytics question.
Access tokens on google servers are good for one hour.
The refresh token does not expire and you can use it as many times as you want to request a new access token.
You should still handle invalid refresh tokens in your code. The user can revoke your access via there Google account. You can have max 50 out standing refresh tokens before the first one starts working. If i authenticate your application you will be given a refresh token if i do it again you get another refresh token there can be max 50 of them outstanding.
If the refresh token does become invalid you should just request authentication from your user again. The library you are using should be handling refreshing the access token for you.
I have an instance of Thinktecture's Identity Server v3 in Azure hosted as WebApp. In general, it works as expected but I have some issues trying to use refresh token through the token identity/connect/token endpoint with the refresh_token grant type. I have a client which uses Authorization Code flow and this is the settings related to the refresh token options regarding this client:
// refresh token options
AccessTokenType = AccessTokenType.Jwt,
AccessTokenLifetime = 3600,
RefreshTokenUsage = TokenUsage.OneTimeOnly, // Every time generates new refresh token. Not only access token.
RefreshTokenExpiration = TokenExpiration.Sliding,
SlidingRefreshTokenLifetime = 1296000
for people who have worked with this it is clear that I use JWT tokens and my access token is valid for 1 hour and after that, without the need to login again on Identity Server I can use the refresh token and obtain new access and refresh tokens. My refresh token must be valid for 15 days(1296000 sec.). What actually happens is that it doesn't work as expected. For some reason, when I decide to make a call to my REST API(relying party of the Identity Server) one hour and a half after the previous one I get invalid_grant response.
I decided to test it a little bit and made my access token to expire in 2 minutes and my refresh token in 10. Well, then I tried to make a call 1, 2, 3.. minutes after the access token was expired and it was working as expected. I don't really want to do this kind of testing with 1 hour access token so that is why I decided to ask here if someone has been trough that before.
Your access token lifetime is 1 hour and the refresh token lifetime is 15 days.
The token you use when you make a call to the API is the access token. It seems normal to me that you get an error if you make the call 90 minutes after the last time you refreshed the access token. In this case, before making a call the API, you should check if the access token is still valid, and if it's not then refresh it.
As for your testing, down the stack the JwtSecurityTokenHandler class is responsible to validate the token. By default the validation parameters allow a mismatch of 5 minutes to cater for variations of time between systems. Modifying TokenValidationParameters.DefaultClockSkew to a smaller value should help in your case.
there seems to be some conflicting advice on how to get an access token from a refresh token:
This SO answer says passportjs doesn't get involved with refreshing the access token and it should be done via cron job:
Refresh token in Passport.js
This SO answer says "No need for any cron jobs...when the user requests data from the API using an access token that has expired, this should trigger your framework to fail, renew, then retry."
OAuth 2.0 - When should an access token be renewed with refresh token?
What's the simplest way to ensure we're always giving Google a valid access token? Right now, we're just storing the refresh token in the database and never using it, which forces users through the "allow / deny permissions" flow every time their access token expires.
There are a few approaches. One is to just detect when the access token fails (with 401 I believe) and then refresh it and re-use it. However, most of the APIs that yield access tokens also tell you their expiry time, so you can just remember that and, when you’re about to use, if it’s less than say 10 min before expiry time, refresh then. If all else fails you could use the tokeninfo endpoint when you get a new access token, to find out its lifetime.