Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# HttpClient refresh token strategy

Since Microsoft recommends that the HttpClient be created once and reused throughout the life of a program, I wondering how to update DefaultRequestHeaders when for example, the token has expired and need to be refresh.

DefaultRequestHeaders is more over not thread safe (for what I know) and the list of headers defined there, shared by all potentially pending requests. Clear() the list and Add() the header with a new token, seems not the wise thing to do.


Update

To be more precise, I don't want/need to change request headers for every request. Only when I've got a HTTP 401 status code.

like image 779
Philippe Lécaillon Avatar asked Apr 21 '18 07:04

Philippe Lécaillon


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.


1 Answers

Wire up a message handler with your HttpClient when you register the IHttpClient in the DI container registry phase or use another pattern such as a factory or singleton to return an instance of the IHttpClient with a custom message handler. Inspect the outbound call and add the necessary headers.

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/httpclient-message-handlers

Sample header message handler

class MessageHandler1 : DelegatingHandler
    {


    private int _count = 0;

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        System.Threading.Interlocked.Increment(ref _count);
        request.Headers.Add("X-Custom-Header", _count.ToString());
        return base.SendAsync(request, cancellationToken);
    }
}

Sample logger message handler:

class LoggingHandler : DelegatingHandler

{
    StreamWriter _writer;

public LoggingHandler(Stream stream)
{
    _writer = new StreamWriter(stream);
}

protected override async Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
    var response = await base.SendAsync(request, cancellationToken);

    if (!response.IsSuccessStatusCode)
    {
        _writer.WriteLine("{0}\t{1}\t{2}", request.RequestUri, 
            (int)response.StatusCode, response.Headers.Date);
    }
    return response;
}

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        _writer.Dispose();
    }
    base.Dispose(disposing);
}

}

Add it to the pipeline

HttpClient client = HttpClientFactory.Create(new Handler1(), new Handler2(), new Handler3());

Threading Concerns

Regarding threading concerns or concurrency, the HttpRequestMessage parameter on the SendAsync method will be per request. If you add the header to the request.Headers collection, you will updating headers for that instance of the request only (i.e., not globally )

Or use the Authorization property on the request.Headers instance:

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

Please see MSDN link below

https://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage

If you use DefaultRequestHeaders on a static, shared, singleton, Lifestyle.Singleton, etc, instance of the HttpClient then you will have threading concerns and need proper synchronization to update the DefaultRequestHeaders collection.

like image 67
Brennan Mann Avatar answered Oct 28 '22 05:10

Brennan Mann