【问题标题】:Getting access token within Claims Transformer in ASP.NET Core在 ASP.NET Core 的 Claims Transformer 中获取访问令牌
【发布时间】:2018-06-04 08:54:06
【问题描述】:

我正在开发一组应用程序,包括使用 IdentityServer4 的 Identity Server、.NET Core MVC 应用程序、.NET Core WebAPI。

作为 asp.net 核心 mvc 应用程序的一部分,我使用 AddOpenIdConnect 进行身份验证并执行 options.SaveTokens = true。

但是,作为声明转换的一部分,在TransformAsync 中,我希望能够访问身份服务器提供的访问令牌。这是为了能够调用 api 上的权限端点,以使用声明填充主体,我可以使用这些声明对我的控制器等进行授权。

如果我调用 HttpContext.GetTokenAsync("access_token"),我会因为调用身份验证创建的无限循环而收到 stackoverflowexception,然后再次调用 TransformAsync

首先,这是一种合理的方法吗?通常,TransformAsync 是我填充应用程序权限的地方。有什么方法可以在不再次触发身份验证的情况下访问令牌?

如果我们有点难过,我们将不胜感激!谢谢

编辑:我已经看到有关在 OnTicketReceived 中进行转换的建议 事件。看起来我可以通过那里的属性访问令牌。这是一个更好的地方吗?

【问题讨论】:

  • 我建议您查看创建 ProfileService 并将其添加到管道中很少的额外工作,它会为您提取声明信息并将其放入 JWT 令牌中。不确定这是否是您要找的。起初我也有点难过,但那一点额外的帮助实现了已经在 IS4 中的 IProfileService。然后我只需使用 DI 插入 UserManager<ApplicationUser> 并获取 IUserClaimsPrincipalFactory<ApplicationUser> 并从 Context 中提取用户信息。
  • 感谢您的回复,但我不确定这是否是我们正在寻找的。配置文件服务似乎只是用于添加额外的声明 - 仍然与身份本身相关 - 尚未填充到初始 cookie 中。我们正在寻找的是当我们的用户发出请求时应用程序声称从 API 填充到客户端。谢谢。
  • 是的,OnTicketReceived 或许多其他 OIDC 事件都适用于此。

标签: asp.net-core asp.net-core-mvc openid-connect identityserver4 claims-based-identity


【解决方案1】:

我遇到了同样的问题。我的解决方案是,

覆盖由IdentityServer4.AccessTokenValidation 中间件调用的JwtBearerEvents.TokenValidated 事件。

private Task OnTokenValidated(TokenValidatedContext tokenValidatedContext)
    {
        tokenValidatedContext.HttpContext.Items["access_token"] = (tokenValidatedContext.SecurityToken as JwtSecurityToken).RawData;
        return Task.CompletedTask;
    }

这将利用请求范围内的HttpContext.Items 集合。现在您可以在TransformAsync 方法中检索此访问令牌,如下所示。

var access_token = _httpContextAccessor.HttpContext.Items["access_token"] as string;

请注意,您需要在ClaimsTransformer 中注入IHttpContextAccessor 才能访问HttpContext

【讨论】:

    【解决方案2】:

    我认为您可以注入 IAuthenticationHandlerProvider 服务并使用以下内容:

    1. 按方案名称获取身份验证处理程序。
    2. 通过调用 AuthenticateAsync 获取 AuthenticateResult
    3. 从身份验证属性中获取令牌

      var token = string.Empty;
      var handler = await Handlers.GetHandlerAsync(context, scheme); // i.e. "OIDC"
      var result = await handler.AuthenticateAsync();
      if(result?.Succeeded == true) {
          token = result?.Properties?.GetTokenValue(tokenName);
      }
      

    还没有测试过,但我认为它应该可以工作

    【讨论】:

    • 感谢您的回复。不幸的是,这种方法会导致与我原来的帖子相同的问题。 AuthenticateAsync 触发 TransformAsync 所以我们陷入了无限循环。
    【解决方案3】:

    这个问题发布已经很多年了,但如果你还在寻找问题的解决方案,你可以在OnTokenValidated事件中获取访问令牌。

    OnTokenValidated = tokenValidatedContext =>
    {
        var handler = new JwtSecurityTokenHandler();
        // get access token
        var jsonToken = handler.ReadJwtToken(tokenValidatedContext.TokenEndpointResponse.AccessToken); 
    
        var claims = new List<Claim>();
    
        claims.Add(new Claim("customClaimType", "customClaimValue"));
    
        var appIdentity = new ClaimsIdentity(claims);
    
        tokenValidatedContext.Principal.AddIdentity(appIdentity);
        return Task.CompletedTask;
    
    }
    

    参考:Adding Custom Claims During Authentication

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多