【问题标题】:how to get claims from userinfo endpoint without including them in id token如何从 userinfo 端点获取声明而不将它们包含在 id 令牌中
【发布时间】:2017-09-13 12:56:34
【问题描述】:

我在尝试弄清楚如何正确使用 userinfo 端点时遇到了麻烦。我的示例使用身份服务器 4 作为授权服务器。

假设我有一个显示经过身份验证的用户位置的 js 应用程序。假设我有一些用户商店,它提供包括用户位置在内的声明。已实现 iprofileservice 接口,以便 GetProfileDataAsync 从用户存储中为用户检索用户声明。

js 应用需要有权访问用户的位置声明。一种方法是向 ids 添加一个身份资源,例如

new IdentityResource("test", new [] {"location"})

然后将范围添加到 js 客户端,例如

new Client
{
    ClientId = "js",
    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        "test"
    }
}

然后配置 oidc 库以请求该范围,例如

var config = {
   authority: "http://localhost:5000",
   client_id: "js",
   redirect_uri: "http://localhost:5003/callback.html",
   response_type: "id_token token",
   scope:"openid test",
   post_logout_redirect_uri : "http://localhost:5003/index.html",
};

这样做意味着 id_token 将包含位置声明,并且可以作为用户个人资料的一部分进行访问。当使用身份验证期间收到的访问令牌调用 userinfo 端点时,将返回相同的声明。

但是我反复阅读 (here, for instance),您应该在身份令牌中放入尽可能少的声明,然后使用 userinfo 端点检索其他声明。链接的文章似乎暗示此行为在身份服务器中默认可用。

所以为了做到这一点,使用我上面提到的示例代码,我将从 oidc 配置的请求范围中删除“测试”范围。这意味着 id 令牌将不再填充位置声明。但是,当调用 userinfo 端点时,“测试”范围不在访问令牌中,因此不会将位置声明放入响应中。

基本上我的问题是你应该如何要求从 id 令牌中省略声明,但从 userinfo 端点返回?

oidc 规范似乎也暗示您应该能够使用“claims”请求参数来请求特定的声明,但我找不到任何关于身份服务器(或 auth0 的文档)的文档问题)。

【问题讨论】:

    标签: openid identityserver4 openid-connect


    【解决方案1】:

    如果您仅请求身份令牌,则所有声明都将在该令牌中。如果您同时请求 id_token 和令牌,则只有基本声明将在 id_token 中,所有其他声明都可以从 userinfo 端点检索。

    这是规范建议的。

    https://leastprivilege.com/2016/12/14/optimizing-identity-tokens-for-size/

    【讨论】:

    • 事实证明这在我们的生产环境中按预期工作,但是当我在本地测试时,我总是从 id 令牌以及 userinfo 端点获取声明。
    【解决方案2】:

    我实现此目的的一种方法是使用 IdentityResourceApiResource

    例如,在你的启动> ConfigureServices

        services.AddIdentityServer(x =>
            {
                x.IssuerUri = webServerSettings.Host;
            })
            .AddSigningCredential(webServerSettings.CertificateSubjectDn)
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryIdentityResources(Config.GetIdentityResources());
    

    然后在我的配置中为GetApiResources 设置类似的内容:

    public static IEnumerable<ApiResource> GetApiResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource
                    {
                        Name = "MyApi",
                        ApiSecrets = { new Secret("somesecret".Sha256()) },
                        UserClaims = {
                            JwtClaimTypes.GivenName,
                            JwtClaimTypes.FamilyName,
                            JwtClaimTypes.PreferredUserName
                        },
                        Description = "some description",
                        DisplayName = "my api display name",
                        Enabled = true,
                        Scopes = { new Scope("MyApiScope") }
                    },
    
                    new ApiResource("otherAPI", "Some other API"),
                };
            }
    

    但也有这个GetIdentityResources:

    public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                // The identity scope defines the claims available at the client by calling the 
                // userinfo endpoint, and does not need to match the claims available to the API
                // which are defined as part of the ApiResource above
                new IdentityResource
                {
                    Name = "MyApiIdentityScope",
                    UserClaims = {
                        JwtClaimTypes.Email,
                        JwtClaimTypes.EmailVerified,
                        JwtClaimTypes.PhoneNumber,
                        JwtClaimTypes.PhoneNumberVerified,
                        JwtClaimTypes.GivenName,
                        JwtClaimTypes.FamilyName,
                        JwtClaimTypes.PreferredUserName
                    }
                }
            };
        }
    

    通过这样做,对 GetProfileDataAsync 的调用将具有不同的 RequestedClaimTypes,具体取决于这是通过 UserInfo 端点发出的,还是仅仅来自对令牌的请求。

    【讨论】:

      猜你喜欢
      • 2018-05-28
      • 2021-05-24
      • 1970-01-01
      • 2017-10-11
      • 2016-10-16
      • 2020-01-23
      • 2017-10-05
      • 2017-09-28
      • 1970-01-01
      相关资源
      最近更新 更多