REPOST from Old community | OAuth Refresh token has expired after 90 days

Community Manager


We have encountered an issue on our live environment:

The Multi Factor Authentication does not work anymore.


We try to authenticate using an OAuth Refresh Token (this authentication mechanism has been recommended by the Yammer group "Partner Center Security Guidance", which now has been closed).

But since today, this authentication does not work anymore, but we get the following error message:
invalid_grant: AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-01-02T09:19:53.5422744Z and was inactive for 90.00:00:00.:


But I am absolutely sure that this refresh token has been successfully used yesterday.


The Microsoft documentation says that an OAuth Refresh token should only expired if it has been inactive for 90 days. But our tokens were used. Therefore the tokens should not expire!


Why do we now have a live incident? What went wrong?


Please not that we are selling in 12 different markets, and therefore have 12 different partner accounts, and therefore 24 different OAuth refresh tokens (one for the live environment and one for the sandbox). Therefore it is not this easy to update the 24 OAuth refresh tokens.


What can we do to avoid similar production incidents in the future?


We are regularily using the refresh tokens to get new access tokens. We do this using the call "POST /{tenant}/oauth2/token grant_type=refresh_token&refresh_token=..." (see The response of this call not only contains the access token, but also a new refresh token. At the moment, we ignore the new refresh token that is returned. Should we store and use the new refresh token that is returned by this call, or would the new refresh token also expire at the same time?


Does Microsoft offer a way to find out the expiry time or the issued-at-date of a refresh token?



Please check that you store your token(cache) also after AquireTokenSilent. You will get a new refresh token which you schould use in sequential requests. In my case I did not (correctly) store it, so I used the refresh token which I aquired the first time when I used AquireTokenInteractive. That token will expire after 90 days.


There are two authentication flows: a confidentialclient which authenticates the application. The application has access to the resources of your organisation, but you have little control over who uses the software. This is, even for background processes, not workable when you develop your own software for multiple customers (you cannot guarantee that customer 1 might never access data from customer 2).


In that case you develop a Public Client where you get access via a user's account via AquireTokenInteractive (that method also supports multifactor authentication and it shows any consentscreen necessary). Once you have access you can use AquireTokenSilent to renew the token. Note that AcquireTokenSilent DOES return a refresh token (valid for 90 days), and you should make sure you store this after every request. The refreshtoken is not visible if you look in the debugger, but it is visible if you use Fiddler to view the raw data (and decode the token).


That was in hindside my problem: I created a daemon process for which the interactive flow does not seem logical, and since I had token issues I went for the confidential flow. But there you do not get the consent screens and it does not work with multifactor authentication.


My conclusion: if you are developing 3rd party software then even for background (daemon) processes you could (should) use the publicclient flow. There is no problem with the token process: it will continue to work forever once you aquire a token. Only when your software is 'down' for more than 90 days you will need to log in again (and when access for your app is changed from the client's azure account)


Relevant links:

0 Replies