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

IdentityServer4集成ADFS 2016外部身份提供者未返回角色的问题咨询

解决IdentityServer4集成ADFS 2016时的角色获取与JWT令牌问题

我来帮你梳理下这个问题的解决思路,分两个核心部分来处理:获取角色声明,以及提取ADFS返回的JWT令牌。

一、解决角色声明缺失的问题

你能成功认证但看不到角色,大概率是ADFS声明规则配置或代码里的声明映射逻辑没匹配上,按以下步骤排查:

1. 先确认ADFS端的角色声明配置

ADFS默认不会自动把Active Directory的安全组/角色传递给依赖方,你需要在ADFS的依赖方信任里添加声明规则:

  • 打开ADFS管理控制台,找到你的IdentityServer4对应的依赖方信任
  • 进入「编辑声明规则」,添加一条「发送LDAP属性作为声明」的规则
    • 选择AD作为属性存储,将tokenGroups - Unqualified Names(或你需要的角色属性)映射到输出声明类型http://schemas.microsoft.com/ws/2008/06/identity/claims/role
  • 保存规则后,ADFS才会在认证成功后返回角色声明

2. 调整OpenIdConnect的声明映射逻辑

ADFS返回的角色声明类型是完整的URI,不是简单的role字符串,你需要修改代码里的ClaimAction来正确映射:

// 替换原来的ClaimAction
options.ClaimActions.MapUniqueJsonKey("role", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
// 或者你可以先打印所有声明,确认实际的Type再调整
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash");

3. 在Callback中调试查看所有声明

在ExternalController.Callback()里添加调试代码,确认ADFS返回的所有声明:

public async Task<IActionResult> Callback() {
    var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
    if (result?.Succeeded != true) {
        throw new Exception("External authentication error");
    }

    // 打印所有声明,找到角色对应的Type
    foreach (var claim in result.Principal.Claims)
    {
        Console.WriteLine($"Claim Type: {claim.Type}, Value: {claim.Value}");
    }
}

二、获取ADFS返回的JWT令牌

要拿到ADFS的id_token和access_token,只需在OpenIdConnect配置里添加一行代码,然后在Callback中提取:

1. 开启令牌保存功能

在你的AddOpenIdConnect配置里添加SaveTokens = true,默认这个值是false,不会把令牌存入AuthenticationProperties:

services.AddAuthentication()
    .AddOpenIdConnect("adfs", "ADFS", options => {
        // 其他原有配置...
        options.SaveTokens = true; // 新增这一行
        // 其他原有配置...
    });

2. 在Callback中提取令牌

现在可以从认证结果的Properties里拿到JWT令牌了:

public async Task<IActionResult> Callback() {
    var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
    if (result?.Succeeded != true) {
        throw new Exception("External authentication error");
    }

    // 提取ADFS返回的令牌
    var authProps = result.Properties;
    var idToken = authProps.GetTokenValue("id_token");
    var accessToken = authProps.GetTokenValue("access_token");
    var refreshToken = authProps.GetTokenValue("refresh_token");

    // 可以解析id_token查看角色,比如用JwtSecurityTokenHandler
    var handler = new JwtSecurityTokenHandler();
    var decodedIdToken = handler.ReadJwtToken(idToken);
    var rolesFromToken = decodedIdToken.Claims.Where(c => c.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:17:43