ASP.NET Core 8.0 - Remember Me Or Not

This article will describe the implementation of a configurable AuthenticationProperties, which determines the cookie's lifetime. You should review the earlier articles of the Cookies And Claims Project series. Registered users can download the ASP.NET Core 8.0 - Cookies And Claims Project for free.

Cookies And Claims Project and Article Series

Free project download for registered users!

I developed the Cookies And Claims Project (CACP) to demonstrate a simple cookie authentication scheme and claim-based authorization with a clear and modifiable design. The CACP is developed with Visual Studio 2022 and the MS Long Term Support (LTS) version .NET 8.0 framework. All Errors, Warnings, and Messages from Code Analysis have been mitigated. The CACP implements utilities like an AES Cipher, Password Hasher, native JavaScript client form validation, password requirements UI, Bootstrap Native message modal generator, loading/spinner generator, SignalR online user count, and an automatic idle logout for users with administration permissions.

The CACP implements AuthenticationProperties during the login process. After review, I updated the AuthenticationProperties to allow an optional Remember me? checkbox on the Login page. The CACP implements a static class named AppSettings.cs for global project settings. The CACP AppSettings. LoginRememberMeDays = 10.

AppSettings.cs:
/// <summary>
/// Used to set the <see cref="AuthenticationProperties.AllowRefresh" />,
/// <see cref="AuthenticationProperties.IsPersistent" />, and 
/// <see cref="AuthenticationProperties.ExpiresUtc" /> for the 
/// <see cref="AppSettings.ApplicationScheme" /> cookie. 
/// </summary>
/// <remarks>
/// A zero value will hide the Login page's Remember Me checkbox, set the 
/// <see cref="AuthenticationProperties.AllowRefresh" /> and
/// <see cref="AuthenticationProperties.IsPersistent" /> to false, and set the
/// <see cref="AuthenticationProperties.ExpiresUtc" /> to null. This will require the user to log in again
/// after all browser instances have closed. A value greater than zero will display the Remember Me
/// checkbox and set the <see cref="AuthenticationProperties.AllowRefresh" /> and
/// <see cref="AuthenticationProperties.IsPersistent" /> to the value of the Remember Me checkbox.
/// Sets the <see cref="AuthenticationProperties.ExpiresUtc" /> to UtcNow plus the LoginRememberMeDays value.
/// The <see cref="CookieAuthenticationOptions.ExpireTimeSpan" /> default is 14 days. 
/// </remarks>
public static readonly int LoginRememberMeDays = 10;

If AppSettings. LoginRememberMeDays > 0, the Remember me? checkbox is displyed.

Pages > Account > Login.cshtml:
@if (AppSettings.LoginRememberMeDays > 0)
{
    <div class="mb-3 alert alert-primary p-2">
        <div class="form-check form-check-inline">
            <input type="checkbox" class="form-check-input" asp-for="Input.RememberMe" />
            <label class="form-check-label" asp-for="Input.RememberMe">
                @Html.DisplayNameFor(model => model.Input.RememberMe)
            </label>
        </div>
    </div>
}
Remember Me Checkbox.

The AuthenticationProperties determine the lifetime of the authentication cookie. The CACP implements 3 properties: AllowRefresh, IsPersistent, and ExpiresUtc. Mehmet Kordacı wrote "Working with cookie expirations on Asp.Net Core may be a bit confusing. Although settings are simple, varierity of settings can mislead you.". See ASP.Net Core, Cookie Expiration and Mysterious Logout on IIS.

The AllowRefresh property sets a SlidingExpiration. The SlidingExpiration is set to true to instruct the handler to re-issue a new cookie with a new expiration time any time it processes a request which is more than halfway through the expiration window. The re-issued cookie gets a new IssuedUtc = DateTime.UtcNow and ExpiresUtc based on the original timespan.

The IsPersistent property sets whether the authentication session is persisted across multiple requests. When it is set to true, the cookie will be kept until the Expires UTC Date/Time even if you close all browsers or reboot. When it is set to false, the cookie will expire after the Expires UTC Date/Time or when all browser sessions end.

The ExpiresUtc property sets the time at which the authentication ticket expires. An absolute expiration time can be set with ExpiresUtc. To create a persistent cookie, IsPersistent must also be set. Otherwise, the cookie is created with a session-based lifetime and could expire either before or after the authentication ticket that it holds. When ExpiresUtc is set, it overrides the value of the ExpireTimeSpan option of CookieAuthenticationOptions, if set. See MS - Use cookie authentication without ASP.NET Core Identity - Absolute cookie expiration.

Pages > Account > Login.cshtml.cs > OnPost:
AuthenticationProperties authenticationProperties = new()
{
    AllowRefresh = AppSettings.LoginRememberMeDays > 0 && Input.RememberMe,
    IsPersistent = AppSettings.LoginRememberMeDays > 0 && Input.RememberMe,
    ExpiresUtc = AppSettings.LoginRememberMeDays > 0 ? DateTimeOffset.UtcNow.AddDays(AppSettings.LoginRememberMeDays) : null
};

await HttpContext.SignInAsync(
    AppSettings.ApplicationScheme,
    new ClaimsPrincipal(claimsIdentity),
    authenticationProperties);

If the AllowRefresh and IsPersistent are set to true, a frequent authenticated visitor may stay logged in indefinitely. The LoginRememberMeDays setting lets the developer decide if the user can choose to stay logged in and sets the cookie lifetime timespan. If the IsPersistent is set to false, the browser cookie's Expires is set to "When the browsing session ends.". If you want an absolute expiration, set AllowRefresh to false and IsPersistent to true.

Session Exipration
Session Cookie.
Absolute Exipration
Absolute Cookie.

I was confused about when the browsing session ends. A long time ago, I thought it was 20 minutes after you left the site or closed the tab. The browsing session doesn't end until all instances of the current browser are stopped. If you are debugging this behavior, you should check the Task Manager for a running instance after you have closed all browser windows.

Task Manager.

Of course, the best way to forget the authentication cookie is to log out.

Pages > Account > Logout.cshtml.cs > OnPost:
public async Task<IActionResult> OnPostAsync()
{
    await HttpContext.SignOutAsync(AppSettings.ApplicationScheme);
    return RedirectToPage("/Account/Logout");
}
Logged Out Page.
Ken Haggerty
Created 07/17/24
Updated 10/24/24 20:57 GMT

Log In or Reset Quota to read more.

Article Tags:

Authentication
Successfully completed. Thank you for contributing.
Processing...
Something went wrong. Please try again.
Contribute to enjoy content without advertisments.
You can contribute without registering.

Comments(0)

Loading...
Loading...

Not accepting new comments.

Submit your comment. Comments are moderated.

User Image.
DisplayedName - Member Since ?