【问题标题】:Issues with GetProfileDataAsync after upgrade to IdentityServer3 v2.5 from v1.6.3从 v1.6.3 升级到 IdentityServer3 v2.5 后 GetProfileDataAsync 出现问题
【发布时间】:2016-06-02 11:38:47
【问题描述】:

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

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

【问题讨论】:

  • 它的工作原理和以前一样,所以我怀疑你在范围声明的数据迁移方面遇到了问题。
  • @BrockAllen 我们没有更改 ScopeClaims 表中的任何内容。唯一一个 AlwaysIncludeIdToken = true 是 sub,根据 Scopes 表,它具有 openid 范围的 scope_id

标签: identityserver3


【解决方案1】:

规范规定,如果请求访问令牌,则 id_token 应仅包含最少的与用户相关的声明(也称为子声明)。然后可以使用访问令牌从 userinfo 端点检索其他声明。

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

我们有一个错误,这是针对 id_token token 而不是针对 code id_token(您正在使用的)。在此过程中的某个时间点修复了此错误。我想这就是你所看到的行为变化。

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

【讨论】:

  • 感谢您的回复。我们确实在昨天晚些时候在 AuthorizationCodeReceived 中添加了从用户端点获取声明,但现在我们缺少我们也使用的 sub 和 amr 声明
  • 通过读取 GetProfileAsync 中传入的主题声明,修复了丢失的 sub,并修复了 id.AddClaim(new Claim("amr", n.AuthenticationTicket.Identity.FindFirst("amr").Value)); 的 amr 问题
猜你喜欢
  • 2019-06-14
  • 2021-02-20
  • 2020-03-07
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多