C# 如何从IdentityServer4请求用户信息

C# 如何从IdentityServer4请求用户信息,c#,oauth-2.0,openid,identityserver4,claims,C#,Oauth 2.0,Openid,Identityserver4,Claims,我有一个使用ResourceOwnerPasswordgrant类型的基本登录流。用户可以登录,验证密码,并获得一个令牌,用于访问API。我现在正试图将索赔传回客户,以便确定我正在处理的用户类型,但我发现了一个我认为与客户范围有关的错误(尽管我看不出是什么) 下面的代码进行了删节,以避免出现一页又一页的代码,但我相信它包含了所有相关的内容。这是identity server设置: services .AddIdentityServer() .AddInMemoryC

我有一个使用
ResourceOwnerPassword
grant类型的基本登录流。用户可以登录,验证密码,并获得一个令牌,用于访问API。我现在正试图将索赔传回客户,以便确定我正在处理的用户类型,但我发现了一个我认为与客户范围有关的错误(尽管我看不出是什么)

下面的代码进行了删节,以避免出现一页又一页的代码,但我相信它包含了所有相关的内容。这是identity server设置:

services
    .AddIdentityServer()       
    .AddInMemoryClients(IdentityServerHelper.GetClients())
    .AddInMemoryApiResources(IdentityServerHelper.GetApiResources())
    .AddTestUsers(IdentityServerHelper.GetUsers())
    .AddInMemoryIdentityResources(
          IdentityServerHelper.GetIdentityResources());
助手方法:

internal static IEnumerable<Client> GetClients()
{
    var clients = new List<Client>
    {
        new Client
        {
            ClientId = "MyClientApp",                    
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,                    
            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },
            AllowedScopes =
            {
                "myApi",
                "Role",
                IdentityServerConstants.StandardScopes.OpenId
                /*
                IdentityServerConstants.StandardScopes.Profile
                */
            }
        }
    };
}

internal static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource> {
        new IdentityResource {
            Name = "Role",
            UserClaims = new List<string> { JwtClaimTypes.Role },

        }
    };
}

internal static List<TestUser> GetUsers()
{
    var users = new List<TestUser>
    {
            new TestUser
            {
                SubjectId = Guid.NewGuid(),
                Username = "user",
                Password = "pass",
                Claims = new List<Claim>()
                {
                    new Claim(JwtClaimTypes.Role, "Role1")
                }
            },
编辑:

在范围中指定openid时,Identity Server日志中出现以下错误:

失败:IdentityServer4.Validation.ScopeValidator[0] 不允许请求的作用域:openid


当您请求令牌时,至少需要添加
openid
范围。像下面这样更改代码可能会解决这个问题

var clients = new List<Client>
{
    new Client
    {
        ClientId = "MyClientApp",                    
        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,                    
        ClientSecrets =
        {
            new Secret("secret".Sha256())
        },
        AllowedScopes =
        {
            "myApi",
            "Role",
            IdentityServerConstants.StandardScopes.OpenId
        }
    }
};

var response = await _httpClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
    Address = _discoveryResponse.TokenEndpoint,
    ClientId = "MyClientApp",
    ClientSecret = "secret",
    Scope = "openid Role myApi",
    UserName = username,
    Password = password
});
var客户机=新列表
{
新客户
{
ClientId=“MyClientApp”,
AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,
客户秘密=
{
新密码(“Secret.Sha256())
},
允许范围=
{
“myApi”,
“角色”,
IdentityServerConstants.StandardScopes.OpenId
}
}
};
var response=await\u httpClient.RequestPasswordTokenAsync(新的PasswordTokenRequest
{
地址=_discoveryResponse.TokenEndpoint,
ClientId=“MyClientApp”,
ClientSecret=“secret”,
Scope=“openid角色myApi”,
用户名=用户名,
密码=密码
});

您可以从

中看到源代码部分,这是我自己得出的结论。但是,当我添加时,我得到一个“无效范围”错误,甚至无法登录。如您所见,我确实为OpenId添加了AllowedScope,但没有效果。您是否同时添加了OpenId客户端配置和令牌请求?是-如果“客户端配置”是指设置新的客户端列表。在这种情况下,yesIt应为Role或myApi未在idsrv上配置。您可以在myApi范围中包含角色声明。但如果尚未将“角色”添加到idsrv,则它不是有效的作用域。示例中可能配置了“角色”作用域。在这种情况下,您应该请求“openid角色myApi”
var clients = new List<Client>
{
    new Client
    {
        ClientId = "MyClientApp",                    
        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,                    
        ClientSecrets =
        {
            new Secret("secret".Sha256())
        },
        AllowedScopes =
        {
            "myApi",
            "Role",
            IdentityServerConstants.StandardScopes.OpenId
        }
    }
};

var response = await _httpClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
    Address = _discoveryResponse.TokenEndpoint,
    ClientId = "MyClientApp",
    ClientSecret = "secret",
    Scope = "openid Role myApi",
    UserName = username,
    Password = password
});