設定 ASP.NET Core Identity
ASP.NET Core Identity 會針對密碼原則、鎖定和 cookie 設定等設定使用預設值。 可以在應用程式啟動時覆寫這些設定。
Identity 選項
IdentityOptions 類別代表可用於設定 Identity 系統的選項。 必須先呼叫 AddIdentity 或 AddDefaultIdentity,然後才能設定 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();
}
上述程式碼是以 Login
Identity 範本為基礎。
鎖定選項是在 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 要求密碼包含大寫字元、小寫字元、數位和非英數字元。 密碼的長度至少必須要有六個字元。
密碼是使用下列方式設定的:
Program.cs
中的 PasswordOptions。Password
屬性中的[StringLength]
屬性 (如果 Identity 已在應用程式中建立 Scaffold)。InputModel
Password
屬性可在下列檔案中找到:Areas/Identity/Pages/Account/Register.cshtml.cs
Areas/Identity/Pages/Account/ResetPassword.cshtml.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 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 |
Cookie 設定
在 Program.cs
中設定應用程式的 cookie。 必須先呼叫 ConfigureApplicationCookie,之後才能呼叫 AddIdentity
或 AddDefaultIdentity
。
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 。 |
在下列範例中,IterationCount 在 Program.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 系統的選項。 必須先呼叫 AddIdentity
或 AddDefaultIdentity
,然後才能設定 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();
}
上述程式碼是以 Login
Identity 範本為基礎。
鎖定選項是在 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 要求密碼包含大寫字元、小寫字元、數位和非英數字元。 密碼的長度至少必須要有六個字元。
密碼是使用下列方式設定的:
Startup.ConfigureServices
中的 PasswordOptions。Password
屬性中的[StringLength]
屬性 (如果 Identity 已在應用程式中建立 Scaffold)。InputModel
Password
屬性可在下列檔案中找到:Areas/Identity/Pages/Account/Register.cshtml.cs
Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
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 |
Cookie 設定
在 Startup.ConfigureServices
中設定應用程式的 cookie。 必須先呼叫 ConfigureApplicationCookie,之後才能呼叫 AddIdentity
或 AddDefaultIdentity
。
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 。 |
在下列範例中,IterationCount 在 Startup.ConfigureServices
中設定為 12000
:
// using Microsoft.AspNetCore.Identity;
services.Configure<PasswordHasherOptions>(option =>
{
option.IterationCount = 12000;
});
全域要求所有使用者都經過驗證
如需有關如何在全域範圍內要求所有使用者進行驗證的資訊,請參閱需要驗證的使用者。