5
votes

I have been reading the IdentityServer4 issue threads for about a day now, but am still really confused regarding the session/signin cookie expiration.

If I set the cookie expiration from the client like this (I'm using an IdentityServer3 client with IdentityServer4 server in order to enable ASP.NET 4.x webapps to authenticate):

app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                ExpireTimeSpan = new TimeSpan(10, 0, 0),
                SlidingExpiration = true
            });

I can open Chrome developer tools (F12) and look at the cookies and see that they are set to expire as soon as the browser closes (the expiration date on all cookies for IdentityServer are set to expire "1969-12-31T23:59:59.000Z", in other words, the client expiration didn't take).

That is the case regardless of whether I set both client and server authentication options UseTokenLifetime to true or not:

Client side:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                 ...
                 UseTokenLifetime = true,
                 ...

Server side:

services.AddAuthentication()
   .AddOpenIdConnect("MyLoginScheme", "A login scheme", options =>
          ...
          options.UseTokenLifetime = true;
          ...

I'm not sure how to get it to take the client cookie lifetime I've set.

1
I saw this page again (about overriding cookie handler): identityserver4.readthedocs.io/en/release/topics/signin.html and I put that part in where you set the cookie expiration on the authentication cookie. Still, in Chrome, I see the same cookie expiration as above after sign-in. - JakeJ
github.com/IdentityServer/IdentityServer4/issues/662 That thread basically offers the same advice as the documentation page. After setting the middleware on the IdSrv side as in my above comment's doc link, I see IdSrv puts a bunch more information in that cookie, but expiration is not set as I tell it to, at least according to Chrome developer tools' Storage/Cookies information. - JakeJ
OK, so I broke it. If I tell IdentityServer to use my cookie, then I change the signin scheme to mine as well, it no longer gets the sub claim from the external identity provider / triggers an exception in the IdentityServer login flow. - JakeJ
I found another way to supposedly set the cookie expiration...not working yet: In IdentityServer Startup, ConfigureServices(): services.AddIdentityServer(options => { options.Authentication.CheckSessionName = "idsrv"; options.Authentication.CookieLifetime = new Timespan(15, 0, 0); }) Still seeing the expiration as 1969 in Chrome devtools. If you hover over CookieLifetime, it says it only works with IdentityServer's provided cookie handlers. Have tried "idsrv" and "idsrv.external" so far, no results. - JakeJ
I've accepted v0id's answer, as it works for at least part of the issue. It sets the expiration of the cookie that the client webapp uses to keep track of the user. There are in fact two cookies, one for the client, and another for identityserver ("idsrv"). I will ask a separate question for the server cookie and link back here. - JakeJ

1 Answers

6
votes

Try this:

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            // …
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = async n =>
                {
                    // Set persistent cookie, 
                    n.AuthenticationTicket.Properties.IsPersistent = true; 
                    // and the expiration
                    n.AuthenticationTicket.Properties.ExpiresUtc = DateTime.Today.AddDays(1); 
                },
            },
            // …
        }

As for the IDS's cookie expiration, you can set it in the ConfigureServices of the Identity Server:

        services.Configure<IdentityOptions>(options =>
        {
            // …
            options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(1);
            // …
        });