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

ASP.NET Core Windows认证下,如何为当前用户从AD获取额外声明?

解决ASP.NET Core Windows认证中获取Active Directory额外声明的问题

Windows认证默认仅会加载用户的基础身份声明(如SID、用户名),要获取Email、NameIdentifier这类额外的AD属性,你可以通过自定义Claims转换的方式实现,具体步骤如下:

1. 安装必要的NuGet包

如果需要通过AD管理API查询用户属性,安装System.DirectoryServices.AccountManagement包:

Install-Package System.DirectoryServices.AccountManagement

2. 实现自定义Claims转换器

创建一个类实现IClaimsTransformation接口,在转换方法中从AD拉取所需属性并添加到用户声明集合:

using System.Security.Claims;
using System.DirectoryServices.AccountManagement;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;

public class AdClaimsTransformer : IClaimsTransformation
{
    private readonly ILogger<AdClaimsTransformer> _logger;

    public AdClaimsTransformer(ILogger<AdClaimsTransformer> logger)
    {
        _logger = logger;
    }

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        // 仅处理Windows认证的用户身份
        if (principal.Identity is not WindowsIdentity windowsIdentity)
        {
            return principal;
        }

        var claimsIdentity = (ClaimsIdentity)principal.Identity;

        try
        {
            // 连接到当前域的AD上下文
            using var principalContext = new PrincipalContext(ContextType.Domain);
            using var userPrincipal = UserPrincipal.FindByIdentity(principalContext, windowsIdentity.Name);

            if (userPrincipal == null)
            {
                return principal;
            }

            // 添加Email声明
            if (!string.IsNullOrWhiteSpace(userPrincipal.EmailAddress))
            {
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Email, userPrincipal.EmailAddress));
            }

            // 添加NameIdentifier声明(用用户SID作为唯一标识,也可改用AD对象GUID)
            var sidClaim = claimsIdentity.FindFirst(ClaimTypes.Sid);
            if (sidClaim != null)
            {
                claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, sidClaim.Value));
            }

            // 可选:添加其他需要的AD属性,比如显示名、部门
            if (!string.IsNullOrWhiteSpace(userPrincipal.DisplayName))
            {
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, userPrincipal.DisplayName));
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to retrieve AD claims for user {UserName}", windowsIdentity.Name);
        }

        return principal;
    }
}

3. 注册Claims转换服务

在Program.cs中注册自定义的Claims转换器:

var builder = WebApplication.CreateBuilder(args);

// 注册Windows认证
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();

// 注册自定义Claims转换器
builder.Services.AddScoped<IClaimsTransformation, AdClaimsTransformer>();

// 其他服务配置...

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

// 中间件路由配置...

app.Run();

注意事项

  • 确保应用池的运行身份具备读取Active Directory用户属性的权限,否则会出现AD查询失败的情况。
  • 如果你的应用部署在非域环境,需要调整PrincipalContext的参数,指定域服务器地址和凭据。
  • NameIdentifier声明没有固定的AD对应属性,这里用SID作为唯一标识是通用方案,你也可以根据需求改用用户的ObjectGUID(需转换为字符串格式)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:38:11