从v1.6.3升级到IdentityServer3 v2.5后,GetProfileDataAsync出现问题

时间:2016-06-02 11:38:47

标签: identityserver3

我们在过去一年中成功运行了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"
  }
}

我们需要做什么才能让它像以前一样请求所有声明类型?

1 个答案:

答案 0 :(得分:1)

规范说如果请求访问令牌,id_token应该只包含最小的与用户相关的声明(aka sub)。然后,可以使用访问令牌从userinfo端点检索其他声明。

这是一种保持id_token尽可能小的优化机制。

我们有一个错误,其中id_token token已完成此操作,但code id_token没有(这是您正在使用的)。在这个过程中的某个时刻修复了这个bug。我想这就是你所看到的行为改变。

在要包含的范围声明中设置AlwaysIncludeInIdToken属性 - 或使用userinfo端点检索声明。