IdentityServer4 将 client_ 附加到声明中

IdentityServer4 appending client_ to claims

我有一个 IdentityServer4 服务器设置并定义了一个客户端:

    public static IEnumerable<Client> Get()
    {
        return new List<Client> {
            new Client {
                ClientId = "oauthClient",
                ClientName = "Example Client Credentials Client Application",
                AllowedGrantTypes = GrantTypes.ClientCredentials,
                ClientSecrets = new List<Secret> {
                    new Secret("superSecretPassword".Sha256())},
                AllowedScopes =     {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    "role",
                    "ControlCenter",
                    "CC.Send",
                },
                Claims = new List<System.Security.Claims.Claim>
                {
                    new System.Security.Claims.Claim("CEO","true"),
                    new System.Security.Claims.Claim(ClaimTypes.Role, "CC.Send"),
                    new System.Security.Claims.Claim(ClaimTypes.Role, "CEO")
                },
                RedirectUris = new List<string> {"https://localhost:44345/signin-oidc", "https://www.getpostman.com/oauth2/callback"},
                PostLogoutRedirectUris = new List<string> {"https://localhost:44345"}
            }
        };
    }

我正在使用邮递员对此进行测试,我可以在 /connect/token 端点获得令牌,但是当我将该令牌传递到 /connect/introspect 端点时,它返回:

{
    "nbf": 1505422619,
    "exp": 1505426219,
    "iss": "https://localhost:44357",
    "aud": [
        "https://localhost:44357/resources",
        "ControlCenter"
    ],
    "client_id": "oauthClient",
    "client_CEO": "true",
    "client_http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
        "CC.Send",
        "CEO"
    ],
    "scope": "CC.Send",
    "active": true
}

这给我带来了麻烦,因为我使用以下方法保护了我的端点:

        services.AddAuthorization(options =>
        {
            options.AddPolicy(
                "CanSendiSuiteProfiles",
                policyBuilder => policyBuilder.RequireClaim("CEO", "true"));
        });

并且由于 CEO <> client_CEO,它返回错误 403。我可以通过查找 client_CEO 非常简单地解决这个问题,但我更愿意了解 client_ 的情况放在我的声明之前。

这些会自动以 IdentityServer4 为前缀,但您可以使用 PrefixClientClaims = false(客户端上的布尔值 属性)关闭前缀。

以下是 IdentityServer4 中 DefaultClaimService 的源代码: https://github.com/IdentityServer/IdentityServer4/blob/295026919db5bec1b0c8f36fc89e8aeb4b5a0e3f/src/IdentityServer4/Services/DefaultClaimsService.cs

if (request.Client.PrefixClientClaims)
{
    claimType = "client_" + claimType;
}

更新: 从 IdentityServer4 v.2 及更高版本开始,属性 bool PrefixClientClaims 被 属性 string ClientClaimsPrefix 取代,它允许您配置您选择的前缀。

if (request.Client.ClientClaimsPrefix.IsPresent())
{
    claimType = request.Client.ClientClaimsPrefix + claimType;
}