【问题标题】:IdentityServer4 can not read all claimsIdentityServer4 无法读取所有声明
【发布时间】:2019-11-12 10:13:13
【问题描述】:

我在 asp.net core 2.2 中使用 IdentityServer4。

我的获取个人资料数据是:

 public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        var principal = await _claimsFactory.CreateAsync(user);

        var claims = principal.Claims.ToList();

        claims.Add(new Claim(ClaimTypes.NameIdentifier, "fullname"));

        context.IssuedClaims = claims;
    }

我添加了如下客户端:

 new Client
            {
                ClientId = "client",
                ClientName = "Application",
                AllowedGrantTypes = GrantTypes.Hybrid,
                ClientSecrets =
                {
                    new Secret("secret".Sha256())
                },
                RedirectUris           = { "http://localhost:45876/signin-oidc" },
                PostLogoutRedirectUris = { "http://localhost:45876/signout-callback-oidc" },
                AllowedCorsOrigins = new[] { "http://localhost:45876/" },
                AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "webapi"
                    },
                AllowOfflineAccess = true
            },

当我在客户端阅读声明时,我有一些声明并非全部主题。 NameIdentifier 为空?

httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

我的问题是什么?我该怎么办?

【问题讨论】:

  • 我认为这里可能存在多个问题。首先,有两种代币和不同的受众。客户端使用与 api 不同的映射。此外,默认情况下,身份资源声明在身份令牌和访问令牌中均不可用。客户端应联系 UserInfo 端点以请求身份资源声明。对于 Mvc 客户端,您可以设置选项 GetClaimsFromUserInfoEndpoint 以将身份资源声明包含到访问令牌中,或者按照 here 的说明使用配置包含它们。

标签: asp.net-core identityserver4 claims


【解决方案1】:

Profile Service 将帮助动态添加用户的声明。该声明可以添加到身份令牌、访问令牌或用户信息端点中。常量IdentityServerConstants.ProfileDataCallers 包含不同的常量值。可以通过过滤context.Caller来追踪逻辑。

关注 ID Token 的长度,默认情况下,声明不会包含在 ID 令牌中。您可以使用以下解决方案之一将自定义声明添加到客户端应用的用户声明原则:

  1. 在客户端应用程序中,您可以在 OpenID 连接选项中设置 options.GetClaimsFromUserInfoEndpoint = true,以便客户端应用程序向 OIDC 的 userinfo 端点发送请求以获取额外的声明,然后您可以使用 ClaimActions.MapJsonKey 将声明映射到用户声明/饼干:

    options.GetClaimsFromUserInfoEndpoint = true;
    options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, ClaimTypes.NameIdentifier);
    
  2. 另一种解决方案是在Identity Server中注册客户端时将AlwaysIncludeUserClaimsInIdToken设置为true,这样自定义的claims就会添加到id token中,客户端app会直接将id token中的claims映射到user claim的原则:

    AlwaysIncludeUserClaimsInIdToken =true
    

【讨论】:

    【解决方案2】:

    您必须指定用于从 json 用户数据中选择值的声明并创建声明。这是在OpenIdConnectOptions 中完成的:

    services
    .Authentication()
    .AddOpenIdConnect(options => {
        // For map all claims
        options.ClaimActions.MapAll();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-24
      • 2015-07-07
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多