microsoft-identity-web icon indicating copy to clipboard operation
microsoft-identity-web copied to clipboard

[Question] Token expiration

Open TanguyPa opened this issue 2 years ago • 3 comments

Which version of Microsoft Identity Web are you using? 1.18.0

Where is the issue?

  • Web app
    • [ ] Sign-in users
    • [x] Sign-in users and call web APIs
  • Web API
    • [ ] Protected web APIs (validating tokens)
    • [ ] Protected web APIs (validating scopes)
    • [ ] Protected web APIs call downstream web APIs
  • Token cache serialization
    • [ ] In-memory caches
    • [ ] Session caches
    • [x] Distributed caches
  • Other (please describe)

Is this a new or an existing app? c. This is a new app or an experiment.

Repro

var authCookieExpirationInDays = 14;
var configGraphAPI = configuration.GetSection("GraphAPI");
var initialScopes = configGraphAPI.GetValue<string>("Scopes")?.Split(' ');
var baseUrl = configGraphAPI.GetValue<string>("BaseUrl");
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
        configuration.Bind("AzureAd", options);
        options.UseTokenLifetime = true;
        options.Events.OnTicketReceived = context =>
                {
                    context.Properties.IsPersistent = true;
                    context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(authCookieExpirationInDays);
                    return Task.FromResult(0);
                };                   
    }, cookiesOption =>
    {
        cookiesOption.Cookie.Name = authCookieName;
        cookiesOption.SlidingExpiration = true;                  
    })
    .EnableTokenAcquisitionToCallDownstreamApi(options => configuration.Bind("AzureAd", options), initialScopes)
    .AddMicrosoftGraph(configGraphAPI)
    .AddDistributedTokenCaches();

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = configuration.GetConnectionString("TokenCacheDatabase");
    options.SchemaName = configuration.GetValue<string>("DatabaseSettings:SchemaName");
    options.TableName = configuration.GetValue<string>("DatabaseSettings:TableName");
});

services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
    options.SlidingExpiration = TimeSpan.FromDays(authCookieExpirationInDays);
});

I use these attributes for the controller

[Authorize]
[AuthorizeForScopes(ScopeKeySection = "GraphAPI:Scopes")]

ASP MVC Core 5.0

Expected behavior

I would like the id token to be valid for 14 days (and refreshed after 7 via the SlidingExpiration attribute) so that a user can leave a page open for a long time without risking the loss of his data after submitting a form.

Actual behavior The user is forced to reconnect after ~20 min without having been active on a page. If the request is an ajax request, a CORS error is returned because an attempt is made to redirect to the identity provider. If the request is a post via a classic form, the form data is lost.

Additional context / logs / screenshots / link to code It seems that the expiration of the id token from the distributedcache is ~1h : "iat": 1641970662, "nbf": 1641970662, "exp": 1641974562, The access token is valid ~1h-1h30 and the refresh token 90 days ?

Can the expiration of the id token be the cause of this redirection to the identity provider? If yes, is it possible to ask the identity provider for an id token with a higher expiration time?

TanguyPa avatar Jan 12 '22 07:01 TanguyPa

The problem is probably related to the line :

options.UseTokenLifetime = true;

I think this is the reason why the cookie lifetime is not used. But it doesn't work the way I want it to. The cookie is set with an expiration time of 14 days in the browser, but after more than 20 minutes on the same page, I am redirected to the identity provider after submitting a form. This seems to me to be the default expiration time defined by a session cookie (yet the cookie is a persistent cookie).

Another question,, what are the differences between these two properties ? context.Properties.ExpiresUtc in OnTicketReceived and cookiesOption.ExpireTimeSpan in CookieAuthenticationOptions

TanguyPa avatar Jan 17 '22 13:01 TanguyPa

@TanguyPa is this still repro-ing in the latest version 2.15.5?

context.Properties.ExpiresUtc is a property of the AuthenticationTicket object which is used to store the authentication information for a user. It specifies the date and time when the authentication ticket expires.

cookiesOption.ExpireTimeSpan is a property of the CookieAuthenticationOptions object which is used to configure the cookie middleware for authentication. It specifies the amount of time for which the authentication cookie should be valid.

basically, context.Properties.ExpiresUtc is used to set the expiration time for the authentication ticket, while cookiesOption.ExpireTimeSpan is used to set the expiration time for the authentication cookie.

jennyf19 avatar Nov 27 '23 21:11 jennyf19

Hello, I haven't had a chance to try again, but I posted the issue initially because I had a global problem using the libin an ASP MVC application. In some applications, users have to leave a page open where they fill a form and come back later to submit it. This causes a problem, because between the time the user opens the page and the time the form is submitted, the authentication token has expired. When this happens, the user is redirected to the auth page after submitting the form, and is then redirected back to the page from which they originally submitted the form.

The problem is that the form data are lost and the POST request sent too.

Have you ever had users encounter similar problems, and do you have any recommendations?

Currently, to avoid these problems, I've set up middleware that saves the request in a cache before the user is redirected to be authenticated and then the request is re-executed once the user re-authenticates.

TanguyPa avatar Jan 09 '24 15:01 TanguyPa