This problem had me stumped for a while. We have a Model-View-Controller (MVC) application using Azure Active Directory for authentication. Users were having an issue where they would occasionally lose form data when they were taken to a login 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’s set to expire exactly 60 minutes after it’s issued. If 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 two 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.
Dozens of stack overflow users encountered the same issue with no answers. Everything I could find ultimately traced back to these two resources:
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: