Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient (C#) Intercept Unauthorized (401) and Redirect

I am using Auth0 for user login in my Blazor project, and additionally authenticate the user in a WebAPI endpoint that supplies a jwt for subsequent calls. This all works fine.

If a user's Auth0 login expires, the user gets correctly redirected to a login page.

The problem is when the jwt expires. The user is still authenticated in the web app, but when they hit the WebAPI they get an Unauthorized (401) response as expected.

I'd like to eventually implement code to refresh the token, but for now I would settle for a redirect to a Logout controller to force them to re-authenticate.

I have tried to redirect from a custom handler that inherits from HttpClientHandler:

var unauthorizedHandler = new UnauthorizedHandler();
var httpClient = new HttpClient(unauthorizedHandler);


public class UnauthorizedHandler : HttpClientHandler
{
    private IHttpContextAccessor _httpContextAccessor;

    public void Add(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);
        
        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            _httpContextAccessor.HttpContext.Response.Redirect("/Identity/Logout", true);
        }

        return response;
    }
}

The redirect results in: System.InvalidOperationException: StatusCode cannot be set because the response has already started.

I am also using NSwag's generated C# client, and tried to similarly redirect from the ProcessResponse partial method, but got the same/similar error message.

If I catch the exception and redirect via NavigationManager in the actual Blazor page, it works fine, but I'd like to handle the problem in a cross-cutting way.

How can I intercept an Unauthorized error in the HttpClient and redirect automatically?

like image 357
Phil Sandler Avatar asked Oct 31 '25 18:10

Phil Sandler


1 Answers

I have dealed with similar issues in the past. This is one possible approach I suggest you. First, the errors is indicating that once the http response starts, you can't modify it to add a redirect status code, so based on this try this:

  1. Use an event-based mechanism or custom exception to notify the UI layer, in this case your Blazor page, that an authorized status has been received
  2. I don't see it in the code but just in case make sure the UnauthorizedHandler gets the dependencies it needs using DI
  3. Actually perform the redirection using the 'NavigationManager'

So in summary my idea is to try something like this:

public class UnauthorizedHandler : HttpClientHandler
{
    public event Action UnauthorizedStatusReceived;

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

        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            // Notice this line
            UnauthorizedStatusReceived?.Invoke();
        }

        return response;
    }
}

Then register the handler and the IHttpContextAncessor:

services.AddSingleton<UnauthorizedHandler>();
services.AddHttpContextAccessor();

And finally subscribe to the UnauthorizedStatusReceived event in your Blazor component and use NavigationManager to do the redirect:

@inject UnauthorizedHandler UnauthorizedHandler
@inject NavigationManager NavigationManager

protected override void OnInitialized()
{
    UnauthorizedHandler.UnauthorizedStatusReceived += HandleUnauthorized;
}

private void HandleUnauthorized()
{
    NavigationManager.NavigateTo("/Identity/Logout");
}

I hope this helps you to solve this or get closer to it.

like image 198
Alberto Espinoza Avatar answered Nov 03 '25 09:11

Alberto Espinoza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!