Wakam Fx
Wakam Fx

Reputation: 367

Asp.net Core Persistent Authentication - Custom Cookie Authentication

I'm trying to get a persistent connection so the users only have to use their password once. I've used this doc: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x but the users still get disconnected after a while.

await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    principal,
                    new AuthenticationProperties
                    {
                        IsPersistent = true
                    });

What can I do to get a really persistent connection ?

Upvotes: 6

Views: 8941

Answers (2)

BorisSh
BorisSh

Reputation: 571

There are few things you should notice when implement persistent cookie authentication.

Configure sliding expiration for cookie in Startup.cs. It will be clearer if you explicitly set values that you needed and don't use default settings.

private void ConfigureAuthentication(IServiceCollection services)
{
    services
        .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {                 
            // true by default   
            options.SlidingExpiration = true;

            // 14 days by default
            options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
        });
}

When user check flag "Remember Me" configure cookie to persist across browser sessions and set absolute expiration (as long as you want). This settings will override SlidingExpiration and ExpireTimeSpan. In login action:

List<Claim> claims = new List<Claim>();
// Prepare user claims...
                
var userIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

AuthenticationProperties authenticationProperties = new AuthenticationProperties() { IsPersistent = model.RememberMe };
if (model.RememberMe)
{
    // One month for example
    authenticationProperties.ExpiresUtc = DateTimeOffset.UtcNow.AddMonths(1);
}

await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, authenticationProperties);

Confugure data protection. Remember machineKey in old classic asp.net webforms. Otherwise cookie will be reset after every IIS app pool restart. You should configure data protection before authentication in Startup.cs. To store keys in root folder of your app:

private void ConfigureDataProtection(IServiceCollection services, IWebHostEnvironment environment)
{
    var keysDirectoryName = "Keys";
    var keysDirectoryPath = Path.Combine(environment.ContentRootPath, keysDirectoryName);
    if (!Directory.Exists(keysDirectoryPath))
    {
        Directory.CreateDirectory(keysDirectoryPath);
    }
    services.AddDataProtection()
          .PersistKeysToFileSystem(new DirectoryInfo(keysDirectoryPath))
          .SetApplicationName("YourApplicationName");
}

From docs:

Upvotes: 4

Stephen Vernyi
Stephen Vernyi

Reputation: 798

The persistence granted by IsPersistent is, according to the docs, only meant to imply that the authentication will persist through browsing sessions (that is, it is kept even when the browser is closed). You need a combination of Persistence and to set an expiration time for the cookie. The expiration of the cookie can be set via the CookieAuthenticationOptions (MSDN), using the ExpireTimeSpan option.

Without persistence, expiration of the authentication can be set using the ExpiresUtc option in AuthenticationOptions,

Upvotes: 6

Related Questions