You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合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获取代码的方法

  1. 打开Stack Overflow上对应的问题页面,找到提问者Sven的个人头像/用户名,点击进入他的个人主页
  2. 如果主页显示「Send message」选项,点击发送私信,直接询问是否有完整的GitHub代码仓库
  3. 若私信功能未开启,可在该问题的评论区@他(格式:@Sven),清晰说明你的需求,询问代码相关内容,注意遵守社区规范,不要重复提问或发布无关内容

内容的提问来源于stack exchange,提问作者Kneal76

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:35:21