关于 asp-net-core-identity-patterns
面向 ASP.NET Core Identity 的安全实践指南,尤其适用于 Razor Pages。内容涵盖 .NET 8 及更高版本的配置、加固、测试与可观测性。
主要功能
- 01Identity 设置与配置
- 02Razor Pages 身份验证模式
- 03基于策略的授权指导
- 04Cookie 与登录安全加固
- 05身份验证测试与监控
适用场景
- 01构建注册和登录流程
- 02添加角色、声明或双重身份验证
- 03生产部署前加固 ASP.NET Core Identity
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill asp-net-core-identity-patterns安装后在 Claude Code 中输入/asp-net-core-identity-patterns确认已加载。
详细介绍
你是一名资深 .NET 安全与身份架构师。当任务涉及 ASP.NET Core(尤其是 Razor Pages)中的用户身份验证、注册、登录、角色、声明、双重身份验证、外部登录或授权时,请严格遵循这些模式。优先考虑符合 OWASP 要求、最小权限、可观测性和最小攻击面。目标版本为 .NET 8+,并启用可空引用类型。
原因
ASP.NET Core Identity 提供了强大的成员管理功能(用户、角色、声明、令牌),但其默认设置面向开发者便利,而非生产环境安全加固。配置错误可能导致密码强度不足、会话劫持、用户枚举攻击或合规性问题(GDPR、SOC2)。这些模式可确保安全的默认设置、正确的流程以及可测试的集成。
核心设置(Program.cs / Startup)
- 使用
AddDefaultIdentity<IdentityUser>(),或使用AddIdentity<IdentityUser, IdentityRole>()以支持角色。 - 链接调用
AddEntityFrameworkStores<ApplicationDbContext>()。 - 始终尽早配置选项:
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
// Password policy - enforce strong defaults
options.Password.RequiredLength = 12;
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequiredUniqueChars = 6;
// Lockout - prevent brute force
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// Sign-in requirements
options.SignIn.RequireConfirmedAccount = true; // Email confirmation mandatory
options.SignIn.RequireConfirmedEmail = true;
options.SignIn.RequireConfirmedPhoneNumber = false; // Optional 2FA/SMS
// User settings
options.User.RequireUniqueEmail = true;
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders(); // For password reset, email confirmation, 2FA
- 在
UseRouting()之后添加身份验证和授权中间件:
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
- 全局启用 HTTPS 强制执行:
app.UseHsts();
app.UseHttpsRedirection();
Razor Pages 集成
- 按需选择性地搭建 Identity UI:
dotnet aspnet-codegenerator identity -dc ApplicationDbContext \
--files "Account.Register;Account.Login;Account.Logout;Account.ForgotPassword;Account.ConfirmEmail;Account.Manage.Index;Account.Manage.ChangePassword;Account.Manage.TwoFactorAuthentication"
- 在 PageModel 中注入服务:
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger<RegisterModel> _logger;
public RegisterModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
ILogger<RegisterModel> logger)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
- 始终在表单中验证防伪令牌:使用
@Html.AntiForgeryToken(),并在 POST 处理程序上添加[ValidateAntiForgeryToken]。 - 在受保护的 PageModel 上使用
[Authorize]:
[Authorize(Policy = "RequireAdminRole")]
public class AdminModel : PageModel { ... }
授权模式
- 在可能的情况下,优先使用基于策略的授权,而非基于角色的授权:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdminRole", policy =>
policy.RequireRole("Admin"));
options.AddPolicy("CanEditContent", policy =>
policy.RequireClaim("Permission", "EditContent")
.RequireAuthenticatedUser());
});
- 通过
[Authorize(Policy = "CanEditContent")]或在端点上使用RequireAuthorization()应用策略。
安全加固
- Cookie 配置:
builder.Services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // HTTPS only
options.Cookie.SameSite = SameSiteMode.Strict; // Mitigate CSRF
options.ExpireTimeSpan = TimeSpan.FromDays(14);
options.SlidingExpiration = true;
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
});
- 对敏感应用默认启用双重身份验证:通过
TwoFactorAuthentication页面引导用户完成设置。 - 使用电子邮件确认令牌;在生产环境中,绝不让未经确认的用户自动登录。
- 对登录和注册端点进行速率限制(使用
AspNetCoreRateLimit或中间件)。 - 通过
Microsoft.AspNetCore.Identitymeters(.NET 10+ 新增)记录 Identity 事件,以检测异常。
外部提供程序
- 添加 Google、Microsoft 等提供程序:
builder.Services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = builder.Configuration["Authentication:Google:ClientId"];
options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
});
- 在登录页面中使用
SignInManager.GetExternalAuthenticationSchemesAsync()动态显示方案。
自定义用户 / 声明
- 谨慎扩展
IdentityUser(添加FirstName、LastName等属性):
public class ApplicationUser : IdentityUser
{
public string FullName { get; set; } = string.Empty;
}
- 登录后通过
SignInManager或自定义声明工厂添加声明。
测试与可观测性
- 使用
UserManager/SignInManager模拟对象(Moq)进行单元测试。 - 使用
WebApplicationFactory对身份验证流程进行集成测试。 - 使用 OpenTelemetry / App Insights 监控登录耗时、失败次数和锁定情况。
示例:安全的注册处理程序代码片段
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid) return Page();
var user = CreateUser(); // Factory method
await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
// Send email with confirmation link...
if (_userManager.Options.SignIn.RequireConfirmedAccount)
return RedirectToPage("RegisterConfirmation", new { email = Input.Email });
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
foreach (var error in result.Errors) ModelState.AddModelError(string.Empty, error.Description);
return Page();
}
反模式
- 在生产环境中禁用电子邮件确认 → 会导致虚假 / 垃圾账号。
- 密码策略过弱 → 至少使用 12 个字符并包含复杂度要求。
- 在代码中存储密钥 → 使用 User Secrets / Azure Key Vault。
- 到处使用
[Authorize(Roles = "Admin")]→ 优先使用声明 / 策略。 - 忽略锁定机制 → 会导致暴力破解攻击。
- 在生产环境中发布完整的 Identity UI 资源 → 仅搭建所需页面;排除静态文件。
参考资料
- Microsoft 文档:https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity
- OWASP .NET 速查表:https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html
- .NET 10 Identity 指标:Microsoft.AspNetCore.Identity meter 文档
当任务涉及身份验证 / Identity 时,应用此技能。请与 razor-pages-patterns、web-security-hardening 或 dependency-injection-patterns 交叉参考。
评论
支持 Markdown