You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor WebAssembly调用未授权控制器时HttpClient异常的处理方法

Blazor WebAssembly未授权请求的解决办法

办法一:配置两个独立的HttpClient

你当前的HttpClient绑定了授权消息处理器,没有令牌就会触发异常,最稳妥的方式是分开注册两个客户端:一个处理需要认证的接口,另一个处理公开/未授权接口。

  1. 保留授权版HttpClient(用于需登录的接口)
builder.Services.AddHttpClient(
    "AuthorizedServerAPI", 
    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => 
    sp.GetRequiredService<IHttpClientFactory>().CreateClient("AuthorizedServerAPI"));
  1. 新增无授权版HttpClient(用于公开接口)
builder.Services.AddHttpClient(
    "PublicServerAPI", 
    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

builder.Services.AddScoped(sp => 
    sp.GetRequiredService<IHttpClientFactory>().CreateClient("PublicServerAPI"));
  1. 组件中按需使用
    调用未授权接口时,要么通过工厂创建公开客户端:
@inject IHttpClientFactory HttpClientFactory;

// 发起未授权请求
var publicClient = HttpClientFactory.CreateClient("PublicServerAPI");
await publicClient.PostAsync("UnauthorizedController", someData);

或者直接注入命名客户端(.NET 6及以上版本支持,需用[FromKeyedServices]标记):

@inject [FromKeyedServices("PublicServerAPI")] HttpClient PublicHttpClient;

await PublicHttpClient.PostAsync("UnauthorizedController", someData);

办法二:自定义授权处理器,按需跳过令牌附加

不想维护两个客户端的话,可以自定义一个消息处理器,让它根据请求路径自动判断是否需要附加令牌:

  1. 编写条件授权处理器
public class ConditionalAuthorizationHandler : BaseAddressAuthorizationMessageHandler
{
    public ConditionalAuthorizationHandler(IAccessTokenProvider provider, NavigationManager navigation)
        : base(provider, navigation)
    {
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // 根据实际接口规则调整判断逻辑,比如识别公开接口的路径特征
        if (request.RequestUri?.AbsolutePath.Contains("UnauthorizedController") == true)
        {
            // 跳过令牌附加,直接发送请求
            return await base.SendWithoutTokenAsync(request, cancellationToken);
        }

        // 其他请求正常附加令牌
        return await base.SendAsync(request, cancellationToken);
    }
}
  1. 替换原有处理器注册
    把原来的BaseAddressAuthorizationMessageHandler替换成自定义的处理器:
builder.Services.AddHttpClient(
    "ServerAPI", 
    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<ConditionalAuthorizationHandler>();

builder.Services.AddScoped(sp => 
    sp.GetRequiredService<IHttpClientFactory>().CreateClient("ServerAPI"));

这样同一个HttpClient就能同时处理授权和未授权请求,无需切换实例。

办法三:捕获异常重试(不推荐)

如果只是个别请求临时处理,可以捕获AccessTokenNotAvailableException后,换无授权客户端重发请求:

@inject HttpClient AuthorizedHttpClient;
@inject IHttpClientFactory HttpClientFactory;

try
{
    await AuthorizedHttpClient.PostAsync("UnauthorizedController", someData);
}
catch (AccessTokenNotAvailableException)
{
    var publicClient = HttpClientFactory.CreateClient("PublicServerAPI");
    await publicClient.PostAsync("UnauthorizedController", someData);
}

这种写法冗余且不利于维护,仅适合临时应急场景。


内容的提问来源于stack exchange,提问作者kopieczek.dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:07:45