配置 ASP.NET Core Identity
ASP.NET Core Identity使用密码策略、锁定和cookie配置等设置的默认值。 可以在应用程序启动时重写这些设置。
Identity 选项
IdentityOptions 类表示可用于配置 Identity 系统的选项。 IdentityOptions 必须在调用 AddIdentity 或 AddDefaultIdentity 之后设置。
声明 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();
上述代码将 IdentityOptions LockoutOptions 设置为默认值。
身份验证成功后,将重置失败访问尝试计数并重置时钟。
IdentityOptions.Lockout使用表中所示的属性指定LockoutOptions。
属性 | 说明 | 默认 |
---|---|---|
AllowedForNewUsers | 确定是否可以锁定新用户。 | true |
DefaultLockoutTimeSpan | 发生锁定时用户被锁定的时长。 | 5 分钟 |
MaxFailedAccessAttempts | 启用锁定后,在用户被锁定之前失败的访问尝试次数。 | 5 |
密码
默认情况下,Identity 要求密码包含大写字符、小写字符、数字和非字母数字字符。 密码长度必须至少为六个字符。
使用以下各项配置密码:
Program.cs
中的 PasswordOptions。Password
属性的[StringLength]
特性(如果 Identity构建到应用中)。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。 必须在调用 AddIdentity
或 AddDefaultIdentity
之后调用 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。
密码 Hasher 选项
PasswordHasherOptions 获取和设置密码哈希选项。
选项 | 说明 |
---|---|
CompatibilityMode | 对新密码进行哈希处理时所使用的兼容模式。 默认为 IdentityV3。 哈希密码的第一个字节称为格式标记,指定用于对密码进行哈希处理的哈希算法版本。 根据哈希验证密码时,VerifyHashedPassword 方法会根据第一个字节选择正确的算法。 无论使用哪个版本的算法对密码进行哈希处理,客户端都能够进行身份验证。 设置兼容模式会影响新密码的哈希处理。 |
IterationCount | 使用 PBKDF2 对密码进行哈希处理时所使用的迭代次数。 此值仅在 CompatibilityMode 设置为 IdentityV3 时使用。 此值必须是正整数,默认为 100000 。 |
以下示例在 Program.cs
中将 IterationCount 设置为 12000
:
// using Microsoft.AspNetCore.Identity;
builder.Services.Configure<PasswordHasherOptions>(option =>
{
option.IterationCount = 12000;
});
要求全局范围内的所有用户都进行身份验证
有关如何全局要求所有用户进行身份验证的信息,请参阅需要通过身份验证的用户。
ISecurityStampValidator 和 SignOut 随处可见
应用需要重新生成用户ClaimsPrincipal以响应涉及安全敏感操作的事件。 例如,ClaimsPrincipal
在加入角色、更改密码或其他安全敏感事件中,应重新生成。 Identity使用ISecurityStampValidator接口重新生成ClaimsPrincipal
。 Identity的默认实现向主要的应用程序cookie和双因素cookie注册SecurityStampValidator。 验证程序会挂钩到要调用到Identity的每个cookie的OnValidatePrincipal事件,从而验证用户的安全戳声明是否与cookie中存储的内容保持不变。 验证程序定期调用。 调用间隔是在过于频繁和不够频繁地访问数据存储之间进行权衡。 使用较长的间隔进行检查会导致声明过时。 调用 userManager.UpdateSecurityStampAsync(user)
以迫使在现有下次检查时失效。 更改密码或添加登录后,大多数IdentityUI 帐户和管理页面都会调用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 系统的选项。 IdentityOptions
必须在调用 AddIdentity
或 AddDefaultIdentity
之后设置。
声明 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;
});
上述代码将 IdentityOptions LockoutOptions 设置为默认值。
身份验证成功后,将重置失败访问尝试计数并重置时钟。
IdentityOptions.Lockout使用表中所示的属性指定LockoutOptions。
属性 | 说明 | 默认 |
---|---|---|
AllowedForNewUsers | 确定是否可以锁定新用户。 | true |
DefaultLockoutTimeSpan | 发生锁定时用户被锁定的时长。 | 5 分钟 |
MaxFailedAccessAttempts | 启用锁定后,在用户被锁定之前失败的访问尝试次数。 | 5 |
密码
默认情况下,Identity 要求密码包含大写字符、小写字符、数字和非字母数字字符。 密码长度必须至少为六个字符。
使用以下各项配置密码:
Startup.ConfigureServices
中的 PasswordOptions。Password
属性的[StringLength]
特性(如果 Identity构建到应用中)。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。 必须在调用 AddIdentity
或 AddDefaultIdentity
之后调用 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。
密码 Hasher 选项
PasswordHasherOptions 获取和设置密码哈希选项。
选项 | 说明 |
---|---|
CompatibilityMode | 对新密码进行哈希处理时所使用的兼容模式。 默认为 IdentityV3。 哈希密码的第一个字节称为格式标记,指定用于对密码进行哈希处理的哈希算法版本。 根据哈希验证密码时,VerifyHashedPassword 方法会根据第一个字节选择正确的算法。 无论使用哪个版本的算法对密码进行哈希处理,客户端都能够进行身份验证。 设置兼容模式会影响新密码的哈希处理。 |
IterationCount | 使用 PBKDF2 对密码进行哈希处理时所使用的迭代次数。 此值仅在 CompatibilityMode 设置为 IdentityV3 时使用。 此值必须是正整数,默认为 10000 。 |
以下示例在 Startup.ConfigureServices
中将 IterationCount 设置为 12000
:
// using Microsoft.AspNetCore.Identity;
services.Configure<PasswordHasherOptions>(option =>
{
option.IterationCount = 12000;
});
要求全局范围内的所有用户都进行身份验证
有关如何全局要求所有用户进行身份验证的信息,请参阅需要通过身份验证的用户。