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

基于ADFS、OpenIDConnect与MVC.net的多AD用户登录域信息查询

获取ADFS认证用户的登录来源域信息(多AD场景)

针对你用OpenID Connect + ASP.NET MVC结合ADFS实现三个AD的用户认证,需要获取用户登录来源域的需求,我分享几个实际项目中用过的可行方案:

方案1:从ADFS默认返回的Claims中提取

ADFS在认证成功后,默认会返回包含用户域信息的声明,最常用的是http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname,它的格式通常是域名\用户名,我们可以直接拆分这个值拿到域名。

代码示例(MVC Controller中)

public IActionResult Index()
{
    // 获取Windows账号名Claim
    var windowsAccountClaim = User.Claims.FirstOrDefault(c => 
        c.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname");
    
    if (windowsAccountClaim != null && !string.IsNullOrEmpty(windowsAccountClaim.Value))
    {
        // 拆分出域名部分
        var domainName = windowsAccountClaim.Value.Split('\\')[0];
        // 这里可以把domainName存起来或者用于业务逻辑
        ViewBag.UserDomain = domainName;
    }
    
    return View();
}

注意:要确保OpenID Connect配置中没有过滤这个Claim,在Startup.cs的认证配置里加上options.ClaimActions.MapAll(),或者单独映射这个Claim:

services.AddOpenIdConnect(options =>
{
    // 其他配置(Authority、ClientId等)...
    // 映射所有Claim,避免默认过滤
    options.ClaimActions.MapAll();
});

方案2:在ADFS中配置自定义Claim规则

如果默认的Claim不够用,或者你想直接拿到更清晰的域信息,可以在ADFS服务器上添加自定义声明规则,让它直接返回用户的域信息作为独立Claim。

配置步骤:

  1. 打开ADFS管理控制台,找到你的应用程序信任
  2. 进入「颁发转换规则」标签,点击「添加规则」
  3. 选择「发送LDAP属性作为声明」,点击下一步
  4. 在「属性存储」中选择目标AD,然后在「LDAP属性」里选「域名」(或userPrincipalName这类包含域信息的属性),映射到自定义Claim类型(比如custom:userdomain)
  5. 保存规则

在MVC中读取自定义Claim

var domainClaim = User.Claims.FirstOrDefault(c => c.Type == "custom:userdomain");
if (domainClaim != null)
{
    var domainName = domainClaim.Value;
    // 后续业务处理
}

方案3:通过LDAP查询AD获取域信息

如果上面两种方案都无法实现,你可以在MVC应用中通过LDAP直接查询三个AD服务器,找到用户所属的域。这种方式需要应用程序有访问AD的权限,且效率稍低,建议配合缓存使用。

代码示例

private string GetUserDomainFromAd(string samAccountName)
{
    // 三个AD的LDAP路径
    var adLdapPaths = new List<string> 
    { 
        "LDAP://domain1.yourcompany.com", 
        "LDAP://domain2.yourcompany.com", 
        "LDAP://domain3.yourcompany.com" 
    };

    foreach (var ldapPath in adLdapPaths)
    {
        try
        {
            using (var directoryEntry = new DirectoryEntry(ldapPath))
            {
                using (var directorySearcher = new DirectorySearcher(directoryEntry))
                {
                    // 根据用户名查询用户
                    directorySearcher.Filter = $"(&(objectClass=user)(sAMAccountName={samAccountName}))";
                    directorySearcher.PropertiesToLoad.Add("distinguishedName");

                    var searchResult = directorySearcher.FindOne();
                    if (searchResult != null)
                    {
                        // 从LDAP路径中提取域名,也可从distinguishedName解析
                        var domain = new Uri(ldapPath).Host;
                        return domain;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // 当前AD无法访问或未找到用户,继续尝试下一个
            continue;
        }
    }

    return null; // 三个AD都没找到用户
}

调用时,你可以从Claim中拿到sAMAccountName对应的用户名,传入方法即可查询到所属域。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:38:52