dotnet new mvc -au Individual 是最可靠、最省事的 Identity 起点,它预配好 ApplicationDbContext、ApplicationUser、Account 控制器、AddDefaultIdentity 注册、认证授权中间件顺序及 EF 迁移脚本,开箱即用,避免手动集成时常见的中间件顺序错、Cookie 策略、角色表缺失等问题。

直接用 dotnet new mvc -au Individual 创建项目,是最可靠、最省事的 Identity 身份管理起点。 手动从空模板集成 Identity 容易卡在中间件顺序、服务注册、Cookie 策略或角色表缺失等底层环节,不是代码写错,而是整个认证链路没对齐。
为什么 dotnet new mvc -au Individual 是首选
它生成的项目已预配好:ApplicationDbContext、ApplicationUser 继承自 IdentityUser、完整 Account 控制器(含注册/登录/登出/密码重置)、AddDefaultIdentity<ApplicationUser>() 注册、UseAuthentication() 和 UseAuthorization() 中间件顺序、以及 EF 迁移脚本。所有环节经过官方验证,开箱即用。
常见错误现象包括:HttpContext.User.Identity.IsAuthenticated 始终为 false、UserManager<ApplicationUser> 无法注入、数据库迁移报 “No migrations found”——这些问题在模板项目里根本不会出现。
- 不用手动写
AccountController或Register.cshtml等页面 - 不用纠结
AddIdentity和AddDefaultIdentity的区别 - 连接字符串名默认是
"DefaultConnection",对应appsettings.json里的 key,无需额外对齐
[Authorize(Roles="Admin")] 不生效的三个硬性前提
授权不是加个特性就完事,它依赖三个关键事实同时成立:
- 用户必须已成功调用
SignInManager.PasswordSignInAsync()—— 仅用UserManager.CheckPasswordAsync()不会写入认证 Cookie - 数据库中
AspNetRoles.Name字段值必须严格等于"Admin"(大小写敏感),不是你代码里随便写的字符串 - 该用户必须已通过
UserManager.AddToRoleAsync(user, "Admin")明确分配角色,且 EF 已提交到库;仅在代码里 new 一个 Role 实体不生效
API 场景下还要确认:前端请求是否携带了服务端 Set-Cookie 返回的 Cookie(比如用 Postman 检查 Cookie 请求头是否存在、域名和路径是否匹配)。
从空项目加 Identity 必须做的四件事
如果因架构约束必须从空模板起步,这四步缺一不可,且顺序不能乱:
- 在
Program.cs中调用builder.Services.AddDefaultIdentity<ApplicationUser>(),不是AddIdentity<ApplicationUser, IdentityRole>()—— 后者不带默认策略和 UI 支持 - 紧接着链式调用
.AddEntityFrameworkStores<ApplicationDbContext>(),否则UserManager查不到用户数据 -
app.UseAuthentication()和app.UseAuthorization()必须放在app.UseRouting()之后、app.UseEndpoints()之前 - 数据库连接字符串名(如
"DefaultConnection")必须和AddDbContext中UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))的参数完全一致
最容易被忽略的是角色名的“双重一致性”:EF 实际存进 AspNetRoles.Name 的值,和你在 [Authorize(Roles="...")] 里写的字符串,必须字面完全相同——包括大小写、空格、引号类型。这不是配置问题,是数据问题。


















