【问题标题】:Not getting user "email" as a claim (from jwt token) back from identity server没有从身份服务器获取用户“电子邮件”作为声明(来自 jwt 令牌)
【发布时间】:2019-07-28 22:44:48
【问题描述】:

我在 IdentityServer 上有一个客户端,它允许 openid、profile 和 email 范围:

  return new[] {
            new Client
            {
                ClientId = "TestWebApp",
                ClientSecrets = new [] { new Secret("TestSecret".Sha256()) },
                AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                AllowedScopes = new List<string>{ StandardScopes.OpenId, StandardScopes.Profile,StandardScopes.Email },
            }
        };

我还定义了以下身份资源,

 public static IEnumerable<IdentityResource> IdentityResources()
    {
        return new IdentityResource[] {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email()                
            };
    }

如果声明丢失,我会在创建时明确向用户声明添加电子邮件:

 await _userManager.AddClaimAsync(testUser, new Claim("email", user.Username));

现在从我的登录控制器使用ResourceOwnerPasswordAndClientCredentials 我正在发送身份验证请求:

 var client = new OAuth2Client(new Uri("http://localhost:44322/connect/token"), "TestWebApp", "TestSecret");
 var requestResponse = client.RequestAccessTokenUserName(model.Email, model.Password, "openid profile email");

这很好,我正在拿回范围,但它们都是空白的。

【问题讨论】:

  • 您可能会获得访问令牌,它使您访问到指定的范围。但要获取电子邮件和其他用户信息,您应该获取 id_token
  • 或者您可以调用 UserInfo 端点提供此访问令牌。
  • @SlavaUtesinov,你有文章的例子或参考吗?

标签: c# asp.net-core asp.net-identity identityserver4


【解决方案1】:

当您在 Scopes 上指定这些声明时,您可以在 accesstoken 中包含用户声明。例如,对于 Swagger,如果可用,我们需要包含名称声明,下面我转储了 ApiResource 类应包含的内容。

    {
    "ApiSecrets": [],
    "Scopes": [
        {
            "Name": "SwaggerApi",
            "DisplayName": "SwaggerApi",
            "Description": null,
            "Required": true,
            "Emphasize": false,
            "ShowInDiscoveryDocument": true,
            "UserClaims": ["name","email"]
        }
    ],
    "Enabled": true,
    "Name": "SwaggerApi",
    "DisplayName": "SwaggerApi",
    "Description": null,
    "UserClaims": ["name","email"]
}

将此范围添加到您的客户注册的允许范围。

请求访问令牌。

如果用户有名称声明或电子邮件声明 -> 它应该被添加到访问令牌中。

结果内容访问令牌

  "idp": "oidc",
  "name": "MyUserName",
  "scope": [
    "openid",
    "profile",
    "SwaggerApi"
  ],

【讨论】:

    【解决方案2】:

    当您使用资源所有者密码流程时,您请求的是访问令牌,而不是 id 令牌。因此,在创建访问令牌时,与定义为身份资源的范围相关联的声明不会传递到您注册的配置文件服务实现中。如果您真的想在访问令牌中包含电子邮件,那么我建议您创建一个 api 资源范围,并将“电子邮件”定义为声明类型。

    话虽如此,如果电子邮件被用于身份验证,我建议使用另一个允许身份令牌的登录流程(如果可能)或使用用户信息端点。

    【讨论】:

      【解决方案3】:

      如果您想在 Id 令牌中包含用户声明,您可以在客户端配置中将 AlwaysIncludeUserClaimsInIdToken 设置为 true。

        return new[] {
                  new Client
                  {
                      ClientId = "TestWebApp",
                      ClientSecrets = new [] { new Secret("TestSecret".Sha256()) },
                      AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                      AllowedScopes = new List<string>{ StandardScopes.OpenId, 
                          StandardScopes.Profile,StandardScopes.Email },
                      AlwaysIncludeUserClaimsInIdToken = true
                  }
              };
      

      【讨论】:

      • @Inaie,这对我有用 - 不知道为什么它对你不起作用。
      猜你喜欢
      • 1970-01-01
      • 2019-06-17
      • 2019-07-11
      • 2018-05-15
      • 2015-10-19
      • 2022-12-30
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      相关资源
      最近更新 更多