Asp.net core mvc 这是设置从web应用程序调用API的授权头的好方法吗?

Asp.net core mvc 这是设置从web应用程序调用API的授权头的好方法吗?,asp.net-core-mvc,identityserver4,Asp.net Core Mvc,Identityserver4,我们有一个由IdentityServer保护的web应用程序,它可以访问同样由IdentityServer保护的多个API。我希望为通过NuGet分发的API提供客户端库,并希望始终如一地处理提供访问令牌的问题。看来这会奏效,但我不确定这是否是个好主意。我主要担心的是,它可能会导致每次访问HttpClient时都会创建它。似乎每次我都会得到一个新实例,但如果在注册HttpClient时不进行任何配置,也会出现这种情况 ITokenProvider实现将负责根据需要检索、缓存和刷新访问令牌 ser

我们有一个由IdentityServer保护的web应用程序,它可以访问同样由IdentityServer保护的多个API。我希望为通过NuGet分发的API提供客户端库,并希望始终如一地处理提供访问令牌的问题。看来这会奏效,但我不确定这是否是个好主意。我主要担心的是,它可能会导致每次访问HttpClient时都会创建它。似乎每次我都会得到一个新实例,但如果在注册HttpClient时不进行任何配置,也会出现这种情况

ITokenProvider
实现将负责根据需要检索、缓存和刷新访问令牌

services.AddHttpClient<IMyClient, MyClient>((serviceProvider, httpClient) =>
{
    var tokenProvider = serviceProvider.GetRequiredService<ITokenProvider>();
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenProvider.AccessToken);
});
services.AddHttpClient((serviceProvider,httpClient)=>
{
var tokenProvider=serviceProvider.GetRequiredService();
httpClient.DefaultRequestHeaders.Authorization=新的AuthenticationHeaderValue(“Bearer”,tokenProvider.AccessToken);
});

答案是否定的。您可以在委托中设置标头,但如果需要进行异步调用以获取访问令牌等数据,则该标头将不起作用。更好的方法是创建自定义
DelegatingHandler
实现,如中所述。我的版本是这样的:

public class MyTokenClientMessageHandler : DelegatingHandler
{
    private readonly IMyTokenClient _myTokenClient;

    public MyTokenClientMessageHandler(IMyTokenClient myTokenClient)
    {
        _myTokenClient = myTokenClient;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var accessToken = await _myTokenClient.GetToken();
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        return await base.SendAsync(request, cancellationToken);
    }
}
公共类MyTokenClientMessageHandler:DelegatingHandler
{
私有只读IMyTokenClient\u myTokenClient;
公共MyTokenClientMessageHandler(IMyTokenClient myTokenClient)
{
_myTokenClient=myTokenClient;
}
受保护的覆盖异步任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
var accessToken=await_myTokenClient.GetToken();
request.Headers.Authorization=新的AuthenticationHeaderValue(“承载者”,accessToken);
返回wait base.sendaync(请求、取消令牌);
}
}
并在

services.AddTransient<MyTokenClientMessageHandler>();
services.AddHttpClient<IMyClient, MyClient>(httpClient =>
{
    // set base URL etc.
}).AddHttpMessageHandler<MyTokenClientMessageHandler>();
services.AddTransient();
services.AddHttpClient(httpClient=>
{
//设置基本URL等。
}).AddHttpMessageHandler();