IdentityServerV4参考令牌自省

Pau*_*aul 3 oauth-2.0 jwt openid-connect identityserver4

我已经使用授权代码+ PKCE 与客户端设置了 IdentityServerV4 ,并设置了要引用的访问令牌类型。

new Client
{
    ClientId = "app",
    ClientName = "My Application",
    AllowedGrantTypes = GrantTypes.Code,
    RequireClientSecret = false,
    RedirectUris = { "http://site.example.com:3000/callback" },
    AllowedCorsOrigins = { "http://site.example.com:3000" },
    AllowedScopes = { "openid", "profile", "email" },
    AccessTokenType = AccessTokenType.Reference,
    RequireConsent = false,
    RequirePkce = true
}
Run Code Online (Sandbox Code Playgroud)

我现在想要在客户端应用程序和服务之间设置一个反向代理网关,该网关将在转发请求之前将引用令牌交换为常规签名的 JWT。在设置网关之前,我尝试使用从登录获得的引用令牌调用内省端点来手动执行交换。

我向身份服务器添加了一个称为“网关”的 API ,如下所述,为其提供了一个秘密,并使用具有 API 的 ID 和秘密的 IntrospectionClient 成功调用了此端点,但我收到了 active: false 的响应,并且身份服务器日志显示错误,表明令牌缺少预期范围“网关”。日志中显示的令牌信息仅显示 openid 范围。

new ApiResource("gateway"){
    ApiSecrets = { new Secret("test".Sha256()) }
}
Run Code Online (Sandbox Code Playgroud)

这会导致来自 IdentityServer 的两条日志消息:

fail: IdentityServer4.ResponseHandling.IntrospectionResponseGenerator[0]
      Expected scope gateway is missing in token
info: IdentityServer4.Endpoints.IntrospectionEndpoint[0]
      Success token introspection. Token active: True, for API name: gateway
Run Code Online (Sandbox Code Playgroud)

因此,我的看法是,API 和颁发的令牌之间缺少一些链接,但我已经尝试了我能想到的 Client 和 ApiResource 定义之间的所有范围排列和允许范围,但我不能似乎得到了预期的结果。我已经反复阅读了文档好几次,但我无法完全弄清楚 API 和客户端之间的关系。需要什么样的配置来支持这种类型的设置?

Kah*_*azi 5

看起来您的代理正在使用gateway内省端点的范围,问题是您的令牌没有此gateway范围,因此您总是会得到 active: false响应。

您在这里有两个选择:

  1. 为您的客户端提供gateway范围,并使其在授权请求中将网关范围与其他范围一起发送
new Client
{
    ClientId = "app",
    ClientName = "My Application",
    AllowedGrantTypes = GrantTypes.Code,
    RequireClientSecret = false,
    RedirectUris = { "http://site.example.com:3000/callback" },
    AllowedCorsOrigins = { "http://site.example.com:3000" },
    AllowedScopes = { "openid", "profile", "email", "gateway" }, // add gateway here
    AccessTokenType = AccessTokenType.Reference,
    RequireConsent = false,
    RequirePkce = true
}
Run Code Online (Sandbox Code Playgroud)
  1. 编写自定义IClaimService并将网关范围添加到所有访问令牌。
public class CustomClaimService : IdentityServer4.Services.DefaultClaimsService
{
    public CustomClaimService(IProfileService profile, ILogger<DefaultClaimsService> logger)
        : base(profile, logger)
    {

    }

    public override Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Resources resources, ValidatedRequest request)
    {
        resources.ApiResources.Add(new ApiResource("gateway"));
        return base.GetAccessTokenClaimsAsync(subject, resources, request);
    }
}
Run Code Online (Sandbox Code Playgroud)

您还需CustomClaimService要先IServiceCollection注册AddIdentityServer

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddTransient<IClaimsService, CustomClaimService>();
    services.AddIdentityServer();
    ...
}
Run Code Online (Sandbox Code Playgroud)