ASP.NET Core 3.1 - 2FA Cookie Schemes

This article will demonstrate the implementation of multiple cookie schemes like ASP.NET Core Identity. I will assume you have downloaded the ASP.NET Core 3.1 - Users Without Identity Project or created a new ASP.NET Core 3.1 Razor Pages project. See Tutorial: Get started with Razor Pages in ASP.NET Core. You should review the earlier articles of the Users Without Identity Project series.

Users Without Identity Project and Article Series

The UWIP used the single CookieAuthenticationDefaults. AuthenticationScheme before I implemented 2FA cookie schemes like ASP.NET Core Identity. The UWIP now employs the multiple cookie schemes with ApplicationScheme and 2 additional 2FA schemes TwoFactorUserIdScheme, and TwoFactorRememberMeScheme. I developed a UWIPConstants class to represent the cookie scheme and claim names.

Entities > UWIPConstants.cs:
//
// Summary:
//     Represents values used to configure the cookies and claims.
public class UWIPConstants
{
    //
    // Summary:
    //     The scheme used to identify application authentication cookies.
    public static readonly string ApplicationScheme = "UWIP.ApplicationScheme";
    //
    // Summary:
    //     The scheme used to identify Two Factor authentication cookies for saving the Remember Me state.
    public static readonly string TwoFactorRememberMeScheme = "UWIP.TwoFactorRememberMeScheme";
    //
    // Summary:
    //     The scheme used to identify Two Factor authentication cookies for round tripping user identities.
    public static readonly string TwoFactorUserIdScheme = "UWIP.TwoFactorUserIdScheme";
    //
    // Summary:
    //     The claim type used to hold the user's TwoFactorEnabled state.
    public static readonly string TwoFactorEnabledClaimType = "UWIP.TwoFactorEnabledClaimType";
    //
    // Summary:
    //     The claim type used to redirect a user to the change password page.
    public static readonly string MustChangePasswordClaimType = "UWIP.MustChangePasswordClaimType";
    //
    // Summary:
    //     The value used to identify the source of the Two Factor authentication key.
    public static readonly string TwoFactorLoginProvider = "AppUserTokens";
    //
    // Summary:
    //     The value used to identify the MultiFactor authentication method.
    public static readonly string MultiFactorAuthentication = "MultiFactor";
    //
    // Summary:
    //     The value used to identify the Password only authentication method.
    public static readonly string PasswordAuthentication = "Password";
    //
    // Summary:
    //     The value used to identify the Admins policy.
    public static readonly string AdminsPolicy = "Admins";
    //
    // Summary:
    //     The value used to identify the Admin role.
    public static readonly string AdminRole = "Admin";        

    public UWIPConstants() { }
}

The CookieAuthenticationDefaults .AuthenticationScheme provides default paths for Login, Logout, and AccessDenied.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Events = new CookieAuthenticationEvents
        {
            OnValidatePrincipal = CookieValidator.ValidateAsync
        };
    });

With multiple schemes, you configure the options for each scheme and declare the default scheme with the AddAuthentication parameter.

Edit Startup.cs > ConfigureServices:
services.AddAuthentication(UWIPConstants.ApplicationScheme)
    .AddCookie(UWIPConstants.ApplicationScheme, options =>
    {
        options.LoginPath = "/Account/Login";
        options.LogoutPath = "/Account/Logout";
        options.AccessDeniedPath = "/Account/AccessDenied";
        options.SlidingExpiration = true;
        options.Events = new CookieAuthenticationEvents
        {
            OnValidatePrincipal = CookieValidator.ValidateAsync
        };
    })
    .AddCookie(UWIPConstants.TwoFactorUserIdScheme, options =>
    {
        options.Cookie.Name = UWIPConstants.TwoFactorUserIdScheme;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    })
    .AddCookie(UWIPConstants.TwoFactorRememberMeScheme, options =>
    {
        options.Cookie.Name = UWIPConstants.TwoFactorRememberMeScheme;
    });

The ApplicationScheme cookie is applied when the user is authenticated. The TwoFactorUserIdScheme cookie is applied when a user who has 2FA enabled, successfully signs in with a username and password. The TwoFactorUserIdScheme cookie has a 5 minute ExpireTimeSpan and is used to transfer the user id from the log in page and the 2FA log in page.

The TwoFactorRememberMeScheme cookie is used to optionally remember the browser used with 2FA authentication. This cookie will persist on the browser after the user signs out. Future sign ins by the same user on the same browser will authenticate the user without 2FA verification until the browser is forgotten.

2FA Remember Machine.
2FA Forget Browser.
Update 02/23/2021

I added the Enhanced User Series' article links.

Ken Haggerty
Created 08/20/20
Updated 02/24/21 00:01 GMT

Log In or Reset Quota to read more.

Article Tags:

2FA Authorization
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 ?