Following is a problem that recently had me stumped for a while. We have an MVC application using AzureAD for authentication. Users were having an issue where they would occasionally lose form data when they were taken to a log in page. This was not the age old, I started to fill out a form, then went to lunch, then finished it that afternoon. This was users opening the form, and hitting save a few minutes later.
As it turns out the Azure Authentication Token is a fixed duration, not a sliding window. By default it is set to expire exactly 60 minutes after it is issued. If the users were navigating between normal pages at the time of expiration it would bounce to the login page, automatically issue a new token, and then forward them on to the destination page. However, if they opened a form at 59 minutes and it took 2 minutes to fill out, then when they hit save, they would bounce to the login page, get a new token issued automatically, and then be sent back to the page with a blank form. I should note that the users didn’t actually see a sign in screen; the only indication that it happened was a quick flash of the login URL in the browser’s address bar.
Researching the issue came up with dozens of stack overflow users with the same issue and no answers. Everything I could find ultimately traced back to these two resources:
The takeaways were:
- There is no way to configure the token lifetimes within the portal.
- The minimum lifetime that can be set on an authentication token is 10 minutes – that is going to make testing and debugging a slow process.
- There is something called a refresh token, which seems like something we’ll need but no official Azure samples that use it.
That all seems kind of ranty, but here’s the good news - it was a pretty minor fix in our code base to make it work.
First, update the Nuget Package for Microsoft.IdentityModel.Clients.ActiveDirectory to v3. We previously were using V2. This package is referred to as ADAL in much of the documentation you’ll find out there. This update will require some changes to use async in a few locations, but beyond that is pretty seamless.
Then change our method for void ProcessAuthorizationCodeReceived to ProcessedAuthroizationCodeReceivedAsync. Within that method, the update of the nuget package will require a change in calling AcquireTokenByAuthorizationCode to AcquireTokenByAuthorizationCodeAsync.
Finally, just before the call to AcquireTokenByAuthroizaitonCodeAsync, add a context.AuthenticationTicket.Properties.AllowRefresh=true.
Here’s the updated function: