設定 ASP.NET Core Identity

ASP.NET Core Identity 會針對密碼原則、鎖定和 cookie 設定等設定使用預設值。 可以在應用程式啟動時覆寫這些設定。

Identity 選項

IdentityOptions 類別代表可用於設定 Identity 系統的選項。 必須先呼叫 AddIdentityAddDefaultIdentity然後才能設定 IdentityOptions

宣告 Identity

IdentityOptions.ClaimsIdentity 指定 ClaimsIdentityOptions,後者具有下表所示屬性。

屬性 說明 預設
RoleClaimType 取得或設定用於角色宣告的宣告類型。 ClaimTypes.Role
SecurityStampClaimType 取得或設定用於安全性戳記宣告的宣告類型。 AspNet.Identity.SecurityStamp
UserIdClaimType 取得或設定用於使用者識別碼宣告的宣告類型。 ClaimTypes.NameIdentifier
UserNameClaimType 取得或設定用於使用者名稱宣告的宣告類型。 ClaimTypes.Name

鎖定

鎖定是在 PasswordSignInAsync 方法中設定的:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl ??= Url.Content("~/");

    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
             Input.Password, Input.RememberMe,
             lockoutOnFailure: false);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

上述程式碼是以 LoginIdentity 範本為基礎。

鎖定選項是在 Program.cs 中設定的:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options =>
                                       options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Default Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

上述程式碼會使用預設值來設定 IdentityOptionsLockoutOptions

驗證成功後,會重設失敗的存取嘗試次數,並重設時鐘。

IdentityOptions.Lockout 指定 LockoutOptions,後者具有資料表所示屬性。

屬性 說明 預設
AllowedForNewUsers 判斷是否可以鎖定新的使用者。 true
DefaultLockoutTimeSpan 發生鎖定時,使用者遭到鎖定的時長。 5 分鐘
MaxFailedAccessAttempts 使用者遭到鎖定之前允許的存取嘗試失敗次數上限 (如果已啟用鎖定)。 5

密碼

根據預設,Identity 要求密碼包含大寫字元、小寫字元、數位和非英數字元。 密碼的長度至少必須要有六個字元。

密碼是使用下列方式設定的:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options =>
                                options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Default Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;
});

var app = builder.Build();

// Remaining code removed for brevity.

IdentityOptions.Password 指定 PasswordOptions,後者具有資料表所示屬性。

屬性 說明 預設
RequireDigit 密碼中需要介於 0-9 之間的數位。 true
RequiredLength 密碼長度下限。 6
RequireLowercase 密碼中需要小寫字元。 true
RequireNonAlphanumeric 密碼中需要非英數字元。 true
RequiredUniqueChars 僅適用於 ASP.NET Core 2.0 或更新版本。

需要密碼中的相異字元數。
1
RequireUppercase 密碼中需要大寫字元。 true

登入

下列程式碼會將設定 SignIn 設定 (設定為預設值):

builder.Services.Configure<IdentityOptions>(options =>
{
    // Default SignIn settings.
    options.SignIn.RequireConfirmedEmail = false;
    options.SignIn.RequireConfirmedPhoneNumber = false;
});

IdentityOptions.SignIn 指定 SignInOptions,後者具有資料表所示屬性。

屬性 說明 預設
RequireConfirmedEmail 需要確認的電子郵件才能登入。 false
RequireConfirmedPhoneNumber 需要確認的電話號碼才能登入。 false

語彙基元

IdentityOptions.Tokens 指定 TokenOptions,後者具有資料表所示屬性。

屬性 說明
AuthenticatorTokenProvider 取得或設定 AuthenticatorTokenProvider,用於使用驗證器驗證雙因素登入。
ChangeEmailTokenProvider 取得或設定 ChangeEmailTokenProvider,用於產生電子郵件變更確認電子郵件中使用的權杖。
ChangePhoneNumberTokenProvider 取得或設定 ChangePhoneNumberTokenProvider,用於產生變更電話號碼時所使用的權杖。
EmailConfirmationTokenProvider 取得或設定權杖提供者以用於產生帳戶確認電子郵件中使用的權杖。
PasswordResetTokenProvider 取得或設定 IUserTwoFactorTokenProvider<TUser> 以用於產生密碼重設電子郵件中使用的權杖。
ProviderMap 用於建構使用者權杖提供者,並以金鑰做為提供者名稱。

使用者

builder.Services.Configure<IdentityOptions>(options =>
{
    // Default User settings.
    options.User.AllowedUserNameCharacters =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;

});

IdentityOptions.User 指定 UserOptions,後者具有資料表所示屬性。

屬性 說明 預設
AllowedUserNameCharacters 使用者名稱中允許的字元。 abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
RequireUniqueEmail 要求每個使用者都有唯一的電子郵件。 false

Program.cs 中設定應用程式的 cookie。 必須呼叫 AddIdentityAddDefaultIdentity然後才能呼叫 ConfigureApplicationCookie

builder.Services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.Cookie.Name = "YourAppCookieName";
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.LoginPath = "/Identity/Account/Login";
    // ReturnUrlParameter requires 
    //using Microsoft.AspNetCore.Authentication.Cookies;
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;
});

如需詳細資訊,請參閱CookieAuthenticationOptions

密碼雜湊程式選項

PasswordHasherOptions 可取得和設定密碼雜湊的選項。

選項 描述
CompatibilityMode 雜湊新密碼時所使用的相容性模式。 預設為 IdentityV3。 雜湊密碼的第一個位元組,稱為格式標記,指定用於雜湊密碼的雜湊演算法版本。 針對雜湊驗證密碼時,VerifyHashedPassword 方法會根據第一個位元組選取正確的演算法。 無論使用哪一個版本的演算法來雜湊密碼,用戶端都能夠進行驗證。 設定相容性模式會影響新密碼的雜湊。
IterationCount 使用 PBKDF2 雜湊密碼時所使用的反覆運算數目。 只有 CompatibilityMode 設定為 IdentityV3 時才會使用此值。 值必須是正整數,且預設為 100000

在下列範例中,IterationCountProgram.cs 中設定為 12000

// using Microsoft.AspNetCore.Identity;

builder.Services.Configure<PasswordHasherOptions>(option =>
{
    option.IterationCount = 12000;
});

全域要求所有使用者都經過驗證

如需有關如何在全域範圍內要求所有使用者進行驗證的資訊,請參閱需要驗證的使用者

ISecurityStampValidator 和 SignOut everywhere

應用程式需要重新產生使用者 ClaimsPrincipal,以回應涉及安全性敏感性動作的事件。 例如,加入角色、變更密碼或發生其他安全性敏感性事件時,應該重新產生 ClaimsPrincipal。 Identity 會使用 ISecurityStampValidator 介面重新產生 ClaimsPrincipal。 Identity 的預設實作會向主要應用程式 cookie 和雙因素 cookie 註冊 SecurityStampValidator。 驗證程式會連結至每個 cookie 的 OnValidatePrincipal 事件來呼叫 Identity,進而確認使用者的安全性戳記宣告與儲存在 cookie 中的內容相比沒有變化。 驗證程式會定期呼叫。 要以適當的頻率命中資料存放區,需要對呼叫間隔進行權衡。 如果檢查時間隔時間太長,則會導致宣告過時。 呼叫 userManager.UpdateSecurityStampAsync(user) 可強制現有 cookie 在下一次檢查時失效。 變更密碼或新增登入名之後,大部分的 Identity UI 帳戶和管理頁面都會呼叫 userManager.UpdateSecurityStampAsync(user)。 應用程式可以呼叫 userManager.UpdateSecurityStampAsync(user) 來實作 [從各裝置登出] 動作。

下列醒目提示的程式碼中顯示了變更驗證間隔:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebClaimsPrincipal.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") 
    ?? throw new InvalidOperationException("'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => 
options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

// Force Identity's security stamp to be validated every minute.
builder.Services.Configure<SecurityStampValidatorOptions>(o => 
                   o.ValidationInterval = TimeSpan.FromMinutes(1));

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

ASP.NET Core Identity 會針對密碼原則、鎖定和 cookie 設定等設定使用預設值。 這些設定可以在 Startup 類別中進行覆寫。

Identity 選項

IdentityOptions 類別代表可用於設定 Identity 系統的選項。 必須先呼叫 AddIdentityAddDefaultIdentity然後才能設定 IdentityOptions

宣告 Identity

IdentityOptions.ClaimsIdentity 指定 ClaimsIdentityOptions,後者具有下表所示屬性。

屬性 說明 預設
RoleClaimType 取得或設定用於角色宣告的宣告類型。 ClaimTypes.Role
SecurityStampClaimType 取得或設定用於安全性戳記宣告的宣告類型。 AspNet.Identity.SecurityStamp
UserIdClaimType 取得或設定用於使用者識別碼宣告的宣告類型。 ClaimTypes.NameIdentifier
UserNameClaimType 取得或設定用於使用者名稱宣告的宣告類型。 ClaimTypes.Name

鎖定

鎖定是在 PasswordSignInAsync 方法中設定的:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        var result = await _signInManager.PasswordSignInAsync(Input.Email, 
            Input.Password, Input.RememberMe, 
            lockoutOnFailure: false);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl,
                Input.RememberMe });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

上述程式碼是以 LoginIdentity 範本為基礎。

鎖定選項是在 StartUp.ConfigureServices 中設定的:

services.Configure<IdentityOptions>(options =>
{
    // Default Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;
});

上述程式碼會使用預設值來設定 IdentityOptionsLockoutOptions

驗證成功後,會重設失敗的存取嘗試次數,並重設時鐘。

IdentityOptions.Lockout 指定 LockoutOptions,後者具有資料表所示屬性。

屬性 說明 預設
AllowedForNewUsers 判斷是否可以鎖定新的使用者。 true
DefaultLockoutTimeSpan 發生鎖定時,使用者遭到鎖定的時長。 5 分鐘
MaxFailedAccessAttempts 使用者遭到鎖定之前允許的存取嘗試失敗次數上限 (如果已啟用鎖定)。 5

密碼

根據預設,Identity 要求密碼包含大寫字元、小寫字元、數位和非英數字元。 密碼的長度至少必須要有六個字元。

密碼是使用下列方式設定的:

services.Configure<IdentityOptions>(options =>
{
    // Default Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;
});

IdentityOptions.Password 指定 PasswordOptions,後者具有資料表所示屬性。

屬性 說明 預設
RequireDigit 密碼中需要介於 0-9 之間的數位。 true
RequiredLength 密碼長度下限。 6
RequireLowercase 密碼中需要小寫字元。 true
RequireNonAlphanumeric 密碼中需要非英數字元。 true
RequiredUniqueChars 僅適用於 ASP.NET Core 2.0 或更新版本。

需要密碼中的相異字元數。
1
RequireUppercase 密碼中需要大寫字元。 true

登入

下列程式碼會將設定 SignIn 設定 (設定為預設值):

services.Configure<IdentityOptions>(options =>
{
    // Default SignIn settings.
    options.SignIn.RequireConfirmedEmail = false;
    options.SignIn.RequireConfirmedPhoneNumber = false;
});

IdentityOptions.SignIn 指定 SignInOptions,後者具有資料表所示屬性。

屬性 說明 預設
RequireConfirmedEmail 需要確認的電子郵件才能登入。 false
RequireConfirmedPhoneNumber 需要確認的電話號碼才能登入。 false

語彙基元

IdentityOptions.Tokens 指定 TokenOptions,後者具有資料表所示屬性。

屬性 說明
AuthenticatorTokenProvider 取得或設定 AuthenticatorTokenProvider,用於使用驗證器驗證雙因素登入。
ChangeEmailTokenProvider 取得或設定 ChangeEmailTokenProvider,用於產生電子郵件變更確認電子郵件中使用的權杖。
ChangePhoneNumberTokenProvider 取得或設定 ChangePhoneNumberTokenProvider,用於產生變更電話號碼時所使用的權杖。
EmailConfirmationTokenProvider 取得或設定權杖提供者以用於產生帳戶確認電子郵件中使用的權杖。
PasswordResetTokenProvider 取得或設定 IUserTwoFactorTokenProvider<TUser> 以用於產生密碼重設電子郵件中使用的權杖。
ProviderMap 用於建構使用者權杖提供者,並以金鑰做為提供者名稱。

使用者

services.Configure<IdentityOptions>(options =>
{
    // Default User settings.
    options.User.AllowedUserNameCharacters =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;

});

IdentityOptions.User 指定 UserOptions,後者具有資料表所示屬性。

屬性 說明 預設
AllowedUserNameCharacters 使用者名稱中允許的字元。 abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
RequireUniqueEmail 要求每個使用者都有唯一的電子郵件。 false

Startup.ConfigureServices 中設定應用程式的 cookie。 必須呼叫 AddIdentityAddDefaultIdentity然後才能呼叫 ConfigureApplicationCookie

services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.Cookie.Name = "YourAppCookieName";
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.LoginPath = "/Identity/Account/Login";
    // ReturnUrlParameter requires 
    //using Microsoft.AspNetCore.Authentication.Cookies;
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;
});

如需詳細資訊,請參閱CookieAuthenticationOptions

密碼雜湊程式選項

PasswordHasherOptions 可取得和設定密碼雜湊的選項。

選項 描述
CompatibilityMode 雜湊新密碼時所使用的相容性模式。 預設為 IdentityV3。 雜湊密碼的第一個位元組,稱為格式標記,指定用於雜湊密碼的雜湊演算法版本。 針對雜湊驗證密碼時,VerifyHashedPassword 方法會根據第一個位元組選取正確的演算法。 無論使用哪一個版本的演算法來雜湊密碼,用戶端都能夠進行驗證。 設定相容性模式會影響新密碼的雜湊。
IterationCount 使用 PBKDF2 雜湊密碼時所使用的反覆運算數目。 只有 CompatibilityMode 設定為 IdentityV3 時才會使用此值。 值必須是正整數,且預設為 10000

在下列範例中,IterationCountStartup.ConfigureServices 中設定為 12000

// using Microsoft.AspNetCore.Identity;

services.Configure<PasswordHasherOptions>(option =>
{
    option.IterationCount = 12000;
});

全域要求所有使用者都經過驗證

如需有關如何在全域範圍內要求所有使用者進行驗證的資訊,請參閱需要驗證的使用者