首页 > 解决方案 > IdentityServer4 ADFS 外部不返回角色

问题描述

我使用 Core Identity 的标准模板创建了一个 IdentityServer4 IDP。我希望有一个外部提供商退出 ADFS 2016 服务器。我已将此添加到 Startup.cs 中的 AddAuthentication()

services.AddAuthentication()
                .AddOpenIdConnect("adfs", "ADFS", options =>
                {
                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    options.SignOutScheme = IdentityServerConstants.SignoutScheme;

                    options.Authority = "[AuthURL]";
                    options.ClientId = "[ClientId]";
                    options.ResponseType = "id_token token code";
                    options.Scope.Add("profile");
                    options.Scope.Add("email");

                    options.CallbackPath = "/signin-adfs";
                    options.SignedOutCallbackPath = "/signout-callback-adfs";
                    options.RemoteSignOutPath = "/signout-adfs";

                    options.ClaimActions.Add(new JsonKeyClaimAction("role", null, "role")); 

                     options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                     {
                         NameClaimType = "name",
                         RoleClaimType = "role"
                     }; 

                });

它成功重定向到 ADFS 登录窗口。登录后,它会正确调用 ExternalController.cs CallBack() 并且我确实有成功的身份验证。

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

我遇到的问题是我没有找回完整的用户。我看到索赔,但我没有看到角色。我习惯于看到包含角色列表的 JWT 令牌,但是,我在上面的结果中看不到这些角色。

在此处输入图像描述

如何从针对 ADFS 的身份验证中获取 JWT 令牌,或者返回角色并在结果中?

标签: asp.net-coreidentityserver4adfsasp.net-core-identity

解决方案


在 OIDC 内部添加角色范围:

options.Scope.Add("roles");

在 IDS4 中的 config.cs 中确保您的客户端具有允许的范围:

AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                IdentityServerConstants.StandardScopes.Email,
                IdentityServerConstants.StandardScopes.OfflineAccess, 
                "roles",
            },

如果是 API,请确保 config.cs 具有正确的用户声明:

new ApiResource()
            {
                Name = "API",
                DisplayName = "display",
                ApiSecrets =
                {
                    new Secret("secret".Sha256()),
                    new Secret
                    {
                        Value = "4A04D56554F731CCD123BB574D6918C8C83BDF65",
                        Type = "X509Thumbprint",
                        Description = "Certificate"
                    }
                },
                Scopes = new List<string>(){"postman Web API"},
                Enabled = true,
                UserClaims =
                {
                    JwtClaimTypes.Name,
                    JwtClaimTypes.Email,
                    JwtClaimTypes.Subject,
                    JwtClaimTypes.Role,
                    JwtClaimTypes.Address,
                    JwtClaimTypes.Confirmation,
                    JwtClaimTypes.EmailVerified,
                    JwtClaimTypes.Id,
                    JwtClaimTypes.Profile
                }
            },

推荐阅读