gpt4 book ai didi

IdentityServer4 - RequestedClaimTypes 为空

转载 作者:行者123 更新时间:2023-12-05 06:30:14 24 4
gpt4 key购买 nike

来自 IdentityServer 4 文档:如果请求的范围是身份资源,则 RequestedClaimTypes 中的声明将根据 IdentityResource 中定义的用户声明类型进行填充

这是我的身份资源:

return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Phone(),
new IdentityResources.Email(),
new IdentityResource(ScopeConstants.Roles, new List<string> { JwtClaimTypes.Role })
};

这是我的客户

AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Phone,
IdentityServerConstants.StandardScopes.Email,
ScopeConstants.Roles
},

ProfileService - GetProfileDataAsync 方法:

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 = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();

if (user.Configuration != null)
claims.Add(new Claim(PropertyConstants.Configuration, user.Configuration));

context.IssuedClaims = claims;
}

principal.claims.ToList() 列出了所有声明,但 context.RequestedClaimTypes 为空,因此按 context.RequestedClaimTypes.Contains(claim.Type)) 筛选不返回任何声明。

客户端配置:

let header = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });

let params = new HttpParams()
.append('username', userName)
.append('password', password)
.append('grant_type', 'password')
.append('scope', 'email offline_access openid phone profile roles api_resource')
.append('resource', window.location.origin)
.append('client_id', 'test_spa');

let requestBody = params.toString();

return this.http.post<T>(this.loginUrl, requestBody, { headers: header });

响应类型:

export interface LoginResponse {
access_token: string;
token_type: string;
refresh_token: string;
expires_in: number;
}

有人表示添加 AlwaysIncludeUserClaimsInIdToken = true 可以解决问题 - 我试过了,但没有。

我在这里错过了什么?请帮忙。

最佳答案

您正在使用资源所有者密码流程。这是一个 OAuth2 流程。

OAuth2 并不真正适合“身份数据”。因此,典型的设置是首先获取访问 token (就像您所做的那样),然后您将使用此 token 调用/userinfo 端点,该端点会将用户身份数据发回给您。

因此,在您的 ProfileService 中的第一个请求(获取访问 token )中,RequestedClaimTypes 不会有任何与身份资源(例如个人资料、电子邮件)相关的声明。

但是,在第二次调用(/userinfo 端点)时,您的 ProfileService 将被再次调用 (Caller=UserInfoEndpoint)。 RequestedClaimTypes 现在应该包含您错过的身份声明。

如果您想在单个调用中获取身份数据,那么您应该使用 OpenID 流(例如,使用 response_type=id_token 的隐式)。然后,您将立即获得包含此数据的 ID token (假定 AlwaysIncludeUserClaimsInIdToken 设置为 true)。当您的 ProfileService 被调用时 (Client=ClaimsProviderIdentityToken),RequestedClaimTypes 将包含身份声明。

引用:https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/Services/Default/DefaultClaimsService.cs#L62

关于IdentityServer4 - RequestedClaimTypes 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52685668/

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