Это хороший подход к настройке заголовка авторизации для вызова API из веб-приложения? - PullRequest
0 голосов
/ 26 сентября 2019

У нас есть веб-приложение, защищенное IdentityServer, которое обращается к нескольким API, также защищенным IdentityServer.Я хотел бы предоставить клиентские библиотеки для API, распространяемых через NuGet, и я хочу последовательно обрабатывать предоставление маркера доступа.Похоже, это сработает, но я не уверен, что это хорошая идея.Моя главная проблема заключается в том, что это может привести к созданию HttpClient при каждом обращении к нему.Кажется, что каждый раз я получаю новый экземпляр, но это также имеет место, если не регистрировать конфигурацию при регистрации HttpClient.

Реализация ITokenProvider будет отвечать за извлечение, кэширование иобновляя токен доступа по мере необходимости.

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

1 Ответ

0 голосов
/ 27 сентября 2019

Ответ НЕТ.Вы можете установить заголовок в делегате, но он не будет работать, если вам нужно сделать асинхронный вызов для получения данных, таких как токен доступа.Лучшим подходом является создание пользовательской реализации 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);
    }
}

и зарегистрируйте ее как

services.AddTransient<MyTokenClientMessageHandler>();
services.AddHttpClient<IMyClient, MyClient>(httpClient =>
{
    // set base URL etc.
}).AddHttpMessageHandler<MyTokenClientMessageHandler>();
...