从 v1.6.3 升级到 IdentityServer3 v2.5 后 GetProfileDataAsync 出现问题
Issues with GetProfileDataAsync after upgrade to IdentityServer3 v2.5 from v1.6.3
我们在过去的一年里 运行 IdentityServer3 v1.x 成功,但现在已经从 v1.6.3 升级到 v2.5。
我们有一个实现 IUserService 的自定义 UserService,因此针对新的上下文参数对其进行了修改,我们能够登录,但 GetProfileDataAsync 有问题
为 v1.6.3 构建的 UserService 工作正常,我们可以在 requestedClaimTypes
中看到 12 个请求的声明类型
public Task<IEnumerable<Claim>> GetProfileDataAsync(ClaimsPrincipal subject,
IEnumerable<string> requestedClaimTypes = null)
{
var userClaims = claimsService.GetByUserIdAsync(int.Parse(subject.GetSubjectId()));
var claims =
userClaims.Where(x => requestedClaimTypes != null && requestedClaimTypes.Contains(x.Type));
return Task.FromResult(claims);
}
但是自从升级到v2.5之后,在context.RequestedClaimTypes
中唯一请求的声明类型是sub,而不是我们以前得到的12。获得所有 12 个的唯一方法是将 AlwaysIncludeInIdToken
更改为 true
我们为 v2.5 更新的 UserService 是
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
if (context == null) throw new ArgumentNullException("context");
var subject = context.Subject;
var requestedClaimTypes = context.RequestedClaimTypes;
var userClaims = await _claimsService.GetByUserIdAsync(int.Parse(subject.GetSubjectId()));
if (userClaims != null)
{
var claims = userClaims.Where(x => requestedClaimTypes != null && requestedClaimTypes.Contains(x.Type));
context.IssuedClaims = claims;
}
}
我们使用 SQL 来存储我们的客户和范围,但我们没有更改任何数据,除了使用 IdentityServer3.EntityFramework 提供程序
我们的日志显示正在请求 4 个范围,它们与以前一样具有相关的范围声明
Info: Authorize request validation success {
"ClientId": "MyApp",
"ClientName": "MyApp",
"RedirectUri": "https://xxx:44300/",
"AllowedRedirectUris": [
"https://xxx:44300/"
],
"SubjectId": "9",
"ResponseType": "code id_token",
"ResponseMode": "form_post",
"Flow": "Hybrid",
"RequestedScopes": "openid profile roles user",
"State": "OpenIdConnect.AuthenticationProperties=xxxx",
"Nonce": "xxx",
"SessionId": "xxx",
"Raw": {
"client_id": "MyApp",
"redirect_uri": "https://xxx:44300/",
"response_mode": "form_post",
"response_type": "code id_token",
"scope": "openid profile roles user",
"state": "OpenIdConnect.AuthenticationProperties=xxx",
"nonce": "xxx"
}
}
我们需要做什么才能让它像以前一样请求所有索赔类型?
规范说,如果请求访问令牌,id_token 应该只包含最少的与用户相关的声明(又名 sub)。然后可以使用访问令牌从 userinfo 端点检索其他声明。
这是一种使 id_token 尽可能小的优化机制。
我们有一个错误,这是针对 id_token token
而不是 code id_token
(您正在使用的)。这个错误在这个过程中的某个时候被修复了。我想这就是您看到的行为变化。
在您想要包含的范围声明中设置 AlwaysIncludeInIdToken
属性,或者使用 userinfo 端点检索声明。
我们在过去的一年里 运行 IdentityServer3 v1.x 成功,但现在已经从 v1.6.3 升级到 v2.5。
我们有一个实现 IUserService 的自定义 UserService,因此针对新的上下文参数对其进行了修改,我们能够登录,但 GetProfileDataAsync 有问题
为 v1.6.3 构建的 UserService 工作正常,我们可以在 requestedClaimTypes
public Task<IEnumerable<Claim>> GetProfileDataAsync(ClaimsPrincipal subject,
IEnumerable<string> requestedClaimTypes = null)
{
var userClaims = claimsService.GetByUserIdAsync(int.Parse(subject.GetSubjectId()));
var claims =
userClaims.Where(x => requestedClaimTypes != null && requestedClaimTypes.Contains(x.Type));
return Task.FromResult(claims);
}
但是自从升级到v2.5之后,在context.RequestedClaimTypes
中唯一请求的声明类型是sub,而不是我们以前得到的12。获得所有 12 个的唯一方法是将 AlwaysIncludeInIdToken
更改为 true
我们为 v2.5 更新的 UserService 是
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
if (context == null) throw new ArgumentNullException("context");
var subject = context.Subject;
var requestedClaimTypes = context.RequestedClaimTypes;
var userClaims = await _claimsService.GetByUserIdAsync(int.Parse(subject.GetSubjectId()));
if (userClaims != null)
{
var claims = userClaims.Where(x => requestedClaimTypes != null && requestedClaimTypes.Contains(x.Type));
context.IssuedClaims = claims;
}
}
我们使用 SQL 来存储我们的客户和范围,但我们没有更改任何数据,除了使用 IdentityServer3.EntityFramework 提供程序
我们的日志显示正在请求 4 个范围,它们与以前一样具有相关的范围声明
Info: Authorize request validation success {
"ClientId": "MyApp",
"ClientName": "MyApp",
"RedirectUri": "https://xxx:44300/",
"AllowedRedirectUris": [
"https://xxx:44300/"
],
"SubjectId": "9",
"ResponseType": "code id_token",
"ResponseMode": "form_post",
"Flow": "Hybrid",
"RequestedScopes": "openid profile roles user",
"State": "OpenIdConnect.AuthenticationProperties=xxxx",
"Nonce": "xxx",
"SessionId": "xxx",
"Raw": {
"client_id": "MyApp",
"redirect_uri": "https://xxx:44300/",
"response_mode": "form_post",
"response_type": "code id_token",
"scope": "openid profile roles user",
"state": "OpenIdConnect.AuthenticationProperties=xxx",
"nonce": "xxx"
}
}
我们需要做什么才能让它像以前一样请求所有索赔类型?
规范说,如果请求访问令牌,id_token 应该只包含最少的与用户相关的声明(又名 sub)。然后可以使用访问令牌从 userinfo 端点检索其他声明。
这是一种使 id_token 尽可能小的优化机制。
我们有一个错误,这是针对 id_token token
而不是 code id_token
(您正在使用的)。这个错误在这个过程中的某个时候被修复了。我想这就是您看到的行为变化。
在您想要包含的范围声明中设置 AlwaysIncludeInIdToken
属性,或者使用 userinfo 端点检索声明。