C# “不获取用户”;电邮;作为从identity server返回的声明(来自jwt令牌)

C# “不获取用户”;电邮;作为从identity server返回的声明(来自jwt令牌),c#,asp.net-core,asp.net-identity,identityserver4,C#,Asp.net Core,Asp.net Identity,Identityserver4,我在IdentityServer上有一个客户端,它允许openid、配置文件和电子邮件范围: return new[] { new Client { ClientId = "TestWebApp", ClientSecrets = new [] { new Secret("TestSecret".Sha256()) }, AllowedGrantTy

我在IdentityServer上有一个客户端,它允许openid、配置文件和电子邮件范围:

  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 },
            }
        };
现在,从我的登录控制器使用
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");
这很好,我正在取回示波器,但它们都是空白的


当您在作用域上指定用户声明时,可以在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"
  ],

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


这就是说,如果电子邮件用于身份验证目的,我建议使用另一个允许身份令牌的登录流(如果可能),或者使用用户信息端点。

如果您想在身份令牌中包含用户声明,您可以在客户端配置中将AlwaysInCludeUserClaimsInToken设置为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
            }
        };
returnnew[]{
新客户
{
ClientId=“TestWebApp”,
ClientSecrets=new[]{newsecret(“TestSecret.Sha256())},
AllowedGrantTypes=GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes=新列表{StandardScopes.OpenId,
StandardScopes.Profile,StandardScopes.Email},
AlwaysIncludeUserClaimsInIdToken=真
}
};

您可能会获得访问令牌,该令牌允许您访问指定的作用域。但若要获取电子邮件和其他用户信息,您应该获取id_令牌。或者您可以调用提供此访问令牌的UserInfo端点。@SlavaUtesinov,您是否有文章的示例或引用?您希望使用此
  "idp": "oidc",
  "name": "MyUserName",
  "scope": [
    "openid",
    "profile",
    "SwaggerApi"
  ],
  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
            }
        };