c# - mvc - jwt authentication asp.net core 2



HttpClient instância única com diferentes cabeçalhos de autenticação (1)

Dado que o .net HttpClient foi projetado com a reutilização em mente e se destina a ser de longa duração e vazamentos de memória foram relatados em instâncias de curta duração. Que linhas de guia existem onde você deseja fazer chamadas tranquilas para um determinado endpoint usando tokens de portador diferentes (ou qualquer cabeçalho de autorização) ao chamar o endpoint para vários usuários?

private void CallEndpoint(string resourceId, string bearerToken) {
  httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("bearer", bearerToken);
  var response = await httpClient.GetAsync($"resource/{resourceid}");
}

Dado que o código acima poderia ser chamado por qualquer número de encadeamentos em um aplicativo da Web, é facilmente possível que o conjunto de encabeçamento na primeira linha não seja o mesmo que é usado ao chamar o recurso.

Sem causar contenção usando bloqueios e manter um aplicativo da web sem estado, qual é a abordagem recomendada para criar e descartar HttpClients para um único terminal (minha prática atual é criar um único cliente por terminal)?

Ciclo da vida

Embora o HttpClient implemente indiretamente a interface IDisposable, o uso recomendado do HttpClient é não descartá-lo após cada solicitação. O objeto HttpClient é destinado a viver enquanto seu aplicativo precisar fazer solicitações HTTP. Ter um objeto entre várias solicitações habilita um local para configurar DefaultRequestHeaders e impede que você precise especificar novamente itens como CredentialCache e CookieContainer em todas as solicitações, como era necessário com o HttpWebRequest.

https://src-bin.com


Answer #1

Se os seus cabeçalhos normalmente forem iguais, você pode definir os DefaultRequestHeaders . Mas você não precisa usar essa propriedade para especificar cabeçalhos. Como você determinou, isso simplesmente não funcionaria se você tivesse vários threads usando o mesmo cliente. Alterações nos cabeçalhos padrão feitos em um thread impactariam as solicitações enviadas em outros threads.

Embora você possa definir cabeçalhos padrão no cliente e aplicá-los a cada solicitação, os cabeçalhos são realmente propriedades da solicitação. Então, quando os cabeçalhos são específicos de uma solicitação, basta adicioná-los à solicitação.

request.Headers.Authorization = new AuthenticationHeaderValue("bearer", bearerToken);

Isso significa que você não pode usar os métodos simplificados que não envolvem a criação de um HttpRequest . Você precisará usar

public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)

documentado here .

Exemplo de métodos GET e POST feitos por meio de um método de extensão que permite manipular o cabeçalho da solicitação e mais do HttpRequestMessage antes de enviá-lo:

public static Task<HttpResponseMessage> GetAsync
    (this HttpClient httpClient, string uri, Action<HttpRequestMessage> preAction)
{
    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);

    preAction(httpRequestMessage);

    return httpClient.SendAsync(httpRequestMessage);
}

public static Task<HttpResponseMessage> PostAsJsonAsync<T>
    (this HttpClient httpClient, string uri, T value, Action<HttpRequestMessage> preAction)
{
    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri)
    {
        Content = new ObjectContent<T>
            (value, new JsonMediaTypeFormatter(), (MediaTypeHeaderValue)null)
    };
    preAction(httpRequestMessage);

    return httpClient.SendAsync(httpRequestMessage);
}

Estes poderiam então ser usados ​​como o seguinte:

var response = await httpClient.GetAsync("token",
    x => x.Headers.Authorization = new AuthenticationHeaderValue("basic", clientSecret));




dotnet-httpclient