Shahreyar Butt
Shahreyar Butt

Reputation: 33

Error unprotecting the session cookie. ASP.NET Core Cookie Authentication - Auto Logout Despite Persistent Session

Problem: I have an ASP.NET Core web application using cookie authentication. Users can choose to persist their login (1-year expiration) or have a session-based login (120 minutes expiration). However, we noticed that user sessions are not being persisted, and users are getting logged out unexpectedly—even before the minimum session timeout.

Upon investigating, I checked the authentication cookie in the browser, and it is still present when the auto-logout occurs. This suggests that the cookie is not being validated properly on the server.

Debugging steps taken:

Authentication setup in Program.cs:

var authenticationBuilder = services.AddAuthentication(options =>
{
    options.DefaultScheme = QiranAuthenticationDefaults.AuthenticationScheme; // Use cookies as default
    options.DefaultSignInScheme = QiranAuthenticationDefaults.ExternalAuthenticationScheme;
})
.AddCookie(QiranAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.Cookie.Name = $"{QiranCookieDefaults.Prefix}{QiranCookieDefaults.AuthenticationCookie}";
    options.Cookie.HttpOnly = true;
    options.LoginPath = QiranAuthenticationDefaults.LoginPath;
    options.AccessDeniedPath = QiranAuthenticationDefaults.AccessDeniedPath;
    options.SlidingExpiration = true;

    options.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = async context =>
        {
            var userPrincipal = context.Principal;

            if (userPrincipal == null)
            {
                context.RejectPrincipal();
                await context.HttpContext.SignOutAsync(QiranAuthenticationDefaults.AuthenticationScheme);
                return;
            }

            var lastValidationClaim = userPrincipal.FindFirst("LastValidation");
            var lastValidationTime = lastValidationClaim == null
                ? DateTime.MinValue
                : DateTime.Parse(lastValidationClaim.Value);

            if ((DateTime.UtcNow - lastValidationTime).TotalMinutes < 30) // Revalidate every 30 minutes
            {
                return;
            }

            var username = userPrincipal.FindFirst(ClaimTypes.Name)?.Value;

            if (string.IsNullOrEmpty(username))
            {
                context.RejectPrincipal();
                await context.HttpContext.SignOutAsync(QiranAuthenticationDefaults.AuthenticationScheme);
                return;
            }

            using (var scope = context.HttpContext.RequestServices.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetRequiredService<MData3Context>();
                var user = await dbContext.Members.SingleOrDefaultAsync(m => m.UserName == username);

                if (user == null || (user.Banned.HasValue && user.Banned.Value))
                {
                    context.RejectPrincipal();
                    await context.HttpContext.SignOutAsync(QiranAuthenticationDefaults.AuthenticationScheme);
                    return;
                }
            }

            var identity = (ClaimsIdentity)userPrincipal.Identity;

            if (lastValidationClaim != null)
            {
                identity.TryRemoveClaim(lastValidationClaim);
            }

            identity.AddClaim(new Claim("LastValidation", DateTime.UtcNow.ToString()));

            context.ShouldRenew = true; // Refresh authentication ticket
        }
    };
});

Additional attempts to fix: enabled LoadUserProfile in IIS, but the issue persists. I'm still getting redirected back to the login page after logging in.

Question: why is my authentication cookie not being validated properly, leading to unexpected logouts? How can I fix this issue so that the user session persists correctly?

Upvotes: 0

Views: 25

Answers (0)

Related Questions