替换默认的 HttpClient 以在 IdentityServer3 中进行自省

Replacing default HttpClient for introspection in IdentityServer3

我在基于微服务的系统中使用 IdentityServer3,我们正在 Service Fabric on premise 上为 运行 构建该系统。我想知道是否可以替换用于从我们的 Web API 无状态服务之一调用内省端点的 HttpClient 实例。

使用服务结构,您可以直接调用集群中的其他服务,但要做到这一点,您需要先查询服务注册表以找出服务的特定 url(可能是在集群中的任何节点上)。有 patterns/classes 可以执行此操作,但您需要围绕它包装重试循环,以防服务移动到其他节点、节点脱机等。

另一种方法是调出负载均衡器/API 网关,其中包含 lookup/retry 逻辑,但如果可能,我宁愿不要招致这个额外的跃点。

任何 ideas/help 将不胜感激!

我猜它是为了您引用的令牌验证,并且查看 options 您确实可以设置一个 HttpMessageHandler 来执行请求。

然后您可以实现消息处理程序的 SendAsync 部分,以更改发送请求的 url。

快速示例:

public class MessageHandler1 : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        //Update the request url by replacing the base address to the internal endpoint.
        return base.SendAsync(request, cancellationToken);

    }
}

根据 Poul 的回答,我设法让它与以下代码一起工作:

public class CustomHandler : DelegatingHandler
{
    private static readonly FabricClient FabricClient = new FabricClient();
    private static readonly HttpCommunicationClientFactory CommunicationFactory = new HttpCommunicationClientFactory(new ServicePartitionResolver(() => FabricClient));

    public CustomHandler() : base(new HttpClientHandler()) {}

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var partitionClient = new ServicePartitionClient<HttpCommunicationClient>(CommunicationFactory, new Uri("fabric:/IdentityService/AuthApi"));

        return await partitionClient.InvokeWithRetryAsync(
            async (client) =>
            {
                //replace base address with resolved url of internal endpoint
                request.RequestUri = new Uri(client.Url, request.RequestUri.PathAndQuery);
                return await base.SendAsync(request, cancellationToken);
            }, cancellationToken);
    }
}

请注意,HttpCommunicationClientFactory、HttpCommunicationClient 遵循定义的模式 here

我还必须使用 PublicOrigin 配置 IdSrv,否则 JWT 受众值可能会有所不同,具体取决于服务所在的节点。