asp.net HttpClient(C#)拦截未经授权的(401)并重定向

fykwrbwg  于 12个月前  发布在  .NET
关注(0)|答案(1)|浏览(234)

我在Blazor项目中使用Auth 0进行用户登录,并在为后续调用提供jwt的WebAPI端点中对用户进行身份验证。一切正常。
如果用户的Auth 0登录过期,则用户将被正确重定向到登录页面。
问题是联合武器条约何时到期。用户仍然在Web应用程序中进行身份验证,但当他们点击WebAPI时,他们会收到预期的Unauthorized(401)响应。
我希望最终实现刷新令牌的代码,但现在我将满足于重定向到注销控制器以强制它们重新验证。
我尝试从一个继承自 * HttpClientClient * 的自定义处理程序重定向:

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;
    }
}

重定向导致:System.InvalidOperationException:无法设置StatusCode,因为响应已开始。
我还使用了NSwag生成的C#客户端,并尝试从 ProcessResponse partial方法进行类似的重定向,但得到了相同/类似的错误消息。
如果我在实际的Blazor页面中捕获异常并通过NavigationManager重定向,它可以正常工作,但我希望以横切的方式处理问题。
如何拦截HttpClient中的Unauthorized错误并自动重定向?

8yoxcaq7

8yoxcaq71#

我过去处理过类似的问题。这是我建议你的一种可能的方法。首先,错误表明一旦http响应启动,你就不能修改它来添加重定向状态码,所以在此基础上试试这个:
1.使用基于事件的机制或自定义异常通知UI层(在本例中是Blazor页面)已收到授权状态
1.我在代码中没有看到它,但为了以防万一,请确保Unauthorizedtask使用DI获得所需的依赖项
1.实际上使用'NavigationManager'执行重定向
所以,总的来说,我的想法是尝试这样的东西:

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;
    }
}

然后注册处理程序和IHttpContextAncessor:

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

最后,订阅Blazor组件中的UnauthorizedStatusReceived事件,并使用NavigationManager进行重定向:

@inject UnauthorizedHandler UnauthorizedHandler
@inject NavigationManager NavigationManager

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

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

我希望这能帮助你解决这个问题,或者更接近它。

相关问题