gpt4 book ai didi

c# - 如何从 IdentityServer4 请求用户信息

转载 作者:太空宇宙 更新时间:2023-11-03 12:07:52 25 4
gpt4 key购买 nike

我有一个使用 ResourceOwnerPassword 授权类型的基本登录流程。用户可以登录、验证密码并获得可用于访问 API 的 token 。我现在正试图将声明传递回客户端,以便我可以确定我正在处理的用户类型,但我收到一个错误,我认为这是客户端范围的问题(尽管我看不到什么)。

下面的代码被删节以避免一页又一页的代码,但我相信它包含了所有相关的内容。这是身份服务器设置:

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")
}
},

思路是将Role1返回给客户端。这是客户端代码:

_discoveryResponse = await _httpClient.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
{
Address = "https://localhost:5021",
Policy =
{
ValidateIssuerName = false,
}
});

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

if (response.IsError)
{
return false; // When specifying openid, get invalid scope here
}

_accessToken = response.AccessToken;

. . .

var userInfo = await _httpClient.GetUserInfoAsync(new UserInfoRequest()
{
Address = _discoveryResponse.UserInfoEndpoint,
Token = _accessToken
});

// userInfo is returning "Forbidden" here.

编辑:

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

fail: IdentityServer4.Validation.ScopeValidator[0] Requested scope not allowed: openid

最佳答案

请求 token 时至少需要添加 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
});

您可以从https://github.com/IdentityServer/IdentityServer4/blob/master/src/Validation/Default/UserInfoRequestValidator.cs#L47 查看源代码部分

关于c# - 如何从 IdentityServer4 请求用户信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53986152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com