如何在ASP.NET (.NET 6) Razor应用中用Azure AD实现SSO并仅用Identity管理角色
解决方案:.NET 6 Razor 应用 Azure AD SSO + Identity 权限管理
1. 基础项目初始化(避免默认登录冲突)
- 新建.NET 6 Razor项目时,不要勾选"启用身份验证",手动添加以下NuGet包:
Microsoft.AspNetCore.Authentication.AzureAD.UIMicrosoft.AspNetCore.Identity.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.SqlServer(或你使用的数据库驱动)
2. 配置Azure AD SSO认证
- 在
appsettings.json中添加Azure AD租户配置:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "你的租户域名", "TenantId": "你的租户ID", "ClientId": "应用注册的客户端ID", "CallbackPath": "/signin-oidc" }
- 在
Program.cs中注册Azure AD认证中间件(必须放在Identity配置之前):
builder.Services.AddAuthentication(AzureADDefaults.AuthenticationScheme) .AddAzureAD(options => builder.Configuration.Bind("AzureAd", options));
3. 集成Identity仅用于权限管理
- 创建自定义Identity用户类(无需密码相关字段,因为用Azure AD登录):
public class ApplicationUser : IdentityUser { // 可添加自定义业务字段,无需PasswordHash、SecurityStamp等 }
- 配置DbContext关联Identity与数据库:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } }
- 注册Identity服务,禁用默认登录/注册路由避免冲突:
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => { options.SignIn.RequireConfirmedAccount = false; // 清空Identity默认登录/登出路径,强制使用Azure AD options.Cookies.ApplicationCookie.LoginPath = null; options.Cookies.ApplicationCookie.LogoutPath = null; }) .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();
- 调整中间件顺序,确保认证管道正确执行:
app.UseAuthentication(); app.UseAuthorization(); // 其他中间件(如app.UseStaticFiles()等)...
4. 关联Azure AD用户与Identity角色
- 实现
IClaimsTransformation,将Azure AD登录用户与Identity角色绑定:
public class ClaimsTransformer : IClaimsTransformation { private readonly UserManager<ApplicationUser> _userManager; public ClaimsTransformer(UserManager<ApplicationUser> userManager) { _userManager = userManager; } public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { var azureAdIdentity = principal.Identity as ClaimsIdentity; var userEmail = azureAdIdentity.FindFirst(ClaimTypes.Email)?.Value; if (string.IsNullOrEmpty(userEmail)) return principal; // 查找或自动创建Identity中的用户 var identityUser = await _userManager.FindByEmailAsync(userEmail); if (identityUser == null) { identityUser = new ApplicationUser { UserName = userEmail, Email = userEmail }; await _userManager.CreateAsync(identityUser); } // 将Identity角色添加到当前登录用户的Claims中 var userRoles = await _userManager.GetRolesAsync(identityUser); foreach (var role in userRoles) { azureAdIdentity.AddClaim(new Claim(ClaimTypes.Role, role)); } return principal; } }
- 在
Program.cs中注册该服务:
builder.Services.AddScoped<IClaimsTransformation, ClaimsTransformer>();
5. 权限控制使用Identity角色
- 在Razor页面或控制器中,用
[Authorize(Roles = "Admin")]特性限制访问:
[Authorize(Roles = "Admin")] public class AdminModel : PageModel { // 管理员专属逻辑 }
- 在Razor视图中直接判断角色:
@if (User.IsInRole("Admin")) { <div class="admin-panel">管理员操作区</div> }
关键注意事项
- Azure AD应用注册中需添加
User.Read委托权限,并授予管理员同意。 - 角色管理可通过Identity的
RoleManager和UserManager实现,比如后台页面手动分配角色。 - 所有登录请求会自动跳转到Azure AD,无需启用Identity默认登录界面。
内容的提问来源于stack exchange,提问作者369-shar
相关产品推荐
相关产品推荐

