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

.NET 8 Blazor Web App授权异常行为及期望效果实现问询

.NET 8 Blazor Web App授权异常问题排查与解决方案

问题现象

我在.NET 8 Blazor Web App中遇到了授权相关的异常行为。示例项目基于默认无授权设置的Blazor Web App模板修改而来,手动添加授权配置步骤如下:

  • 安装Microsoft.AspNetCore.Components.WebAssembly.Authentication NuGet包,修改Routes.razor引入AuthorizeRouteView组件;
  • 在Client项目的Program.cs中添加builder.Services.AddAuthorizationCore();;
  • 在Server项目中添加builder.Services.AddAuthentication(BearerTokenDefaults.AuthenticationScheme).AddBearerToken();。

给首页Home.razor添加[Authorize]特性后,期望未授权访问时,Routes.razor中配置的<NotAuthorized>片段显示“Login”文本,但实际首次请求返回401错误,页面无内容。更奇怪的是,即使从App.razor中完全移除Routes组件,未授权时仍会出现401错误;移除Home.razor的[Authorize]特性后,网站正常显示“Hello App”。

原因分析

这种异常的核心原因是Blazor Web App的Server端自动路由保护机制:

  1. 当你在Server端配置AddBearerToken()后,框架会自动对所有Blazor页面的初始渲染请求应用授权检查,直接识别页面上的[Authorize]特性并返回401,完全绕过了客户端AuthorizeRouteView的逻辑。
  2. 即使移除客户端Router组件,Server端处理首页初始请求时,依然会匹配到Home.razor的路由规则和授权特性,触发401拦截。

解决方案

要让客户端AuthorizeRouteView的<NotAuthorized>片段正常生效,需要调整Server端和客户端的配置,让客户端授权逻辑接管页面访问控制:

1. 修改Server端认证配置

取消对Blazor页面初始请求的自动授权,仅保护API端点:

builder.Services.AddAuthentication(BearerTokenDefaults.AuthenticationScheme)
    .AddBearerToken(options =>
    {
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                // 仅对/api开头的请求验证Token
                if (!context.Request.Path.StartsWithSegments("/api"))
                {
                    context.Token = null;
                }
                return Task.CompletedTask;
            }
        };
    });

// 仅保护API控制器,不对Blazor页面入口做授权要求
app.MapControllers().RequireAuthorization();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host"); // 不要给这个端点添加RequireAuthorization

2. 确保客户端AuthorizeRouteView配置正确

在Routes.razor中完善授权视图逻辑:

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
            <NotAuthorized>
                <p>Login</p>
            </NotAuthorized>
            <Authorizing>
                <p>Loading...</p>
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

3. 客户端授权服务初始化

在Client项目的Program.cs中确保授权服务正确注册:

builder.Services.AddAuthorizationCore();
// 若需要自定义认证状态,可添加自定义状态提供器
// builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

4. 验证页面授权特性

确认Home.razor的[Authorize]特性正确应用:

@page "/"
@attribute [Authorize]

<h1>Hello, world!</h1>

完成以上配置后,Server端不再拦截Blazor页面的初始请求,客户端AuthorizeRouteView会接管授权检查,未授权时会正常显示<NotAuthorized>中的“Login”文本。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:06:29