如何结合Windows认证使用.NET Core 6 Identity角色?求原作者完整代码
.NET Core 6 结合Windows认证与Identity用户角色管理方案
一、实现Windows认证自动填充Identity对象
1. 基础服务配置
在Program.cs中同时配置Windows认证和Identity服务,禁用默认登录注册等UI功能:
var builder = WebApplication.CreateBuilder(args); // 配置Windows认证 builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); // 配置Identity,使用默认用户/角色实体,禁用默认UI builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => { options.SignIn.RequireConfirmedAccount = false; }) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); // 设置授权策略,确保Windows认证用户能被Identity体系识别 builder.Services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; });
2. 实现Windows用户到Identity的映射转换
创建IClaimsTransformation实现类,在用户通过Windows认证后,自动从Identity数据库同步用户和角色信息,填充到ClaimsPrincipal中:
public class WindowsIdentityTransformer : IClaimsTransformation { private readonly UserManager<IdentityUser> _userManager; private readonly RoleManager<IdentityRole> _roleManager; public WindowsIdentityTransformer(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager) { _userManager = userManager; _roleManager = roleManager; } public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { // 已完成Identity填充则直接返回 if (principal.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)) return principal; // 提取Windows用户名(处理「域名\用户名」格式) var windowsFullName = principal.Identity.Name; var userName = windowsFullName.Split('\\').Last(); // 查找或自动创建Identity用户(自动创建可根据业务需求关闭) var identityUser = await _userManager.FindByNameAsync(userName); if (identityUser == null) { identityUser = new IdentityUser { UserName = userName, Email = $"{userName}@yourdomain.com" }; var createResult = await _userManager.CreateAsync(identityUser); if (!createResult.Succeeded) throw new InvalidOperationException("同步Windows用户到Identity失败:" + string.Join(", ", createResult.Errors.Select(e => e.Description))); } // 加载用户角色并添加到Claims var userRoles = await _userManager.GetRolesAsync(identityUser); var transformedIdentity = new ClaimsIdentity(principal.Identity.AuthenticationType); // 添加Identity核心标识Claim transformedIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identityUser.Id)); transformedIdentity.AddClaim(new Claim(ClaimTypes.Name, identityUser.UserName)); // 添加角色及角色关联的Claims foreach (var roleName in userRoles) { transformedIdentity.AddClaim(new Claim(ClaimTypes.Role, roleName)); var role = await _roleManager.FindByNameAsync(roleName); if (role != null) { var roleClaims = await _roleManager.GetClaimsAsync(role); transformedIdentity.AddClaims(roleClaims); } } return new ClaimsPrincipal(transformedIdentity); } }
在Program.cs中注册该转换器:
builder.Services.AddScoped<IClaimsTransformation, WindowsIdentityTransformer>();
3. 完全禁用Identity默认UI
如果不需要任何Identity自带的页面,确保项目中不引用Razor Pages相关的UI包,或者在配置时避免添加UI服务,用AddIdentity替代AddDefaultIdentity(如第一步所示),同时路由配置中不要映射默认Identity页面。
二、联系原提问者Sven获取代码的方法
- 打开Stack Overflow上对应的问题页面,找到提问者Sven的个人头像/用户名,点击进入他的个人主页
- 如果主页显示「Send message」选项,点击发送私信,直接询问是否有完整的GitHub代码仓库
- 若私信功能未开启,可在该问题的评论区@他(格式:
@Sven),清晰说明你的需求,询问代码相关内容,注意遵守社区规范,不要重复提问或发布无关内容
内容的提问来源于stack exchange,提问作者Kneal76
相关产品推荐
相关产品推荐

