Search code examples
asp.net-coreasp.net-core-2.0identityserver4oidc-client-js

IdentityServer Session cookie is not sliding


I am facing a weird problem. I am able to do the silent renew, but my IdP cookie is getting sliding. More into the problem...

I have an IdP session cookie (IdentityServer) lifetime set to expire in 15 minutes and I kept the same time for the access token and id token lifetime too.

On my JavaScript client, I check user activity every 2 minutes and if there is activity in the last 2 min, I will renew the token.

I am able to get the access token and id token with renewed expiration times, but after 15 minutes (the IdP cookie life time) silent renew calls are failing and IdP is logging out.
I checked response of silent renew call, I see no cookies being set (with new sliding expiration times) in the response headers.

Are there any settings I am supposed to enable at the server side? Appreciate your help.


Solution

  • As @mackie mentioned in the comments, the cookie will slide only if it's past half way to expiry... and this has nothing to do with Identity Server, but .NET framework

    I was able to overcome it by doing this:

    public class CustomCookieOptions : IConfigureNamedOptions<CookieAuthenticationOptions>
    {
        private readonly AppConfiguration _appConfiguration;
        private const string UTC_DATE_TIME_FORMAT = "r";
        private const string EXPIRES_KEY = ".expires";
    
        public CustomCookieOptions(IOptions<AppConfiguration> appConfiguration)
        {
            _appConfiguration = appConfiguration.Value;
        }
    
        public void Configure(CookieAuthenticationOptions options)
        {
        }
    
        public void Configure(string name, CookieAuthenticationOptions options)
        {
            options.Events.OnValidatePrincipal = context =>
            {
                if (context.Principal.Identity.IsAuthenticated &&
                    options.Cookie.Name == IdentityServerConstants.DefaultCookieAuthenticationScheme)
                {
                    if (context.Properties.Items.ContainsKey(EXPIRES_KEY)
                        && context.Request.Path.Value.StartsWith("/connect/authorize"))
                    {
                        var expiresAt = DateTimeOffset.Parse(context.Properties.Items[EXPIRES_KEY]);
                        if (DateTimeOffset.UtcNow <= expiresAt)
                        {
                            context.ShouldRenew = true;
                            context.Properties.Items[EXPIRES_KEY] =
                                DateTimeOffset.UtcNow.AddSeconds(_appConfiguration.CookieLifetimeInSeconds)
                                    .ToString(UTC_DATE_TIME_FORMAT, CultureInfo.InvariantCulture);
                        }
                    }
                }
                return Task.CompletedTask;
            };
        }
    

    And then register it:

    services.AddSingleton<IConfigureOptions<CookieAuthenticationOptions>, CustomCookieOptions>();