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

Blazor Server C#代码后置中如何正确获取当前认证用户名

问题原因

你的代码存在4个核心错误,和引用/配置缺失无关,都是Blazor组件生命周期和服务使用的写法问题:

  • 未通过依赖注入获取AuthenticationStateProvider实例:Blazor中框架提供的服务必须通过[Inject]特性注入后才能调用,直接使用未实例化的对象会导致调用异常、返回空值。
  • 生命周期方法写法错误:使用了async void修饰OnInitialized方法,正确的异步生命周期重写应该是返回Task的OnInitializedAsync,async void会导致组件渲染流程不会等待认证状态查询完成,状态还未赋值就完成了首次渲染,自然拿到null值。
  • 用户名属性使用了static修饰:静态属性是应用全局共享的,多用户并发访问时会出现用户信息串值的问题,完全不符合Blazor组件实例隔离的设计。
  • 直接调用context.User报错是正常的:context是AuthorizeView组件在Razor模板内生成的局部上下文变量,仅在<AuthorizeView>标签内部可用,后置代码中不存在这个变量,和命名空间引用无关。
修复步骤

1. 确认基础配置正常

首先确认两个基础配置没有遗漏,否则所有认证逻辑都会失效:

  • Program.cs中已经添加Windows认证和授权相关服务:
using Microsoft.AspNetCore.Server.IISIntegration;

var builder = WebApplication.CreateBuilder(args);
// 其他服务添加...
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
builder.Services.AddAuthorization();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// 其他配置...
var app = builder.Build();
// 中间件顺序注意要先加认证、授权,再加载Blazor路由
app.UseAuthentication();
app.UseAuthorization();
// 其他中间件...
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
  • App.razor中最外层使用CascadingAuthenticationState包裹路由组件,保证认证状态可以级联传递到所有子组件:
<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

2. 修正后置代码写法

两种正确的实现方式二选一即可:

方式1:注入AuthenticationStateProvider获取

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;

namespace WebApplication7.Pages
{  
    public partial class Explorer
    {
        // 注入认证状态提供器
        [Inject]
        private AuthenticationStateProvider AuthenticationStateProvider { get; set; } = default!;
        
        // 去掉static修饰,作为组件实例私有属性
        private string? CurrentUserName { get; set; }

        // 重写正确的异步生命周期方法,返回Task
        protected override async Task OnInitializedAsync()
        {                   
            var authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
            CurrentUserName = authenticationState.User.Identity?.Name;
        }
    }
}

方式2:通过级联参数直接获取(写法更简洁)

不需要手动注入服务,直接接收框架级联传递的认证状态任务即可:

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;

namespace WebApplication7.Pages
{  
    public partial class Explorer
    {
        [CascadingParameter]
        private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
        
        private string? CurrentUserName { get; set; }

        protected override async Task OnInitializedAsync()
        {   
            if (AuthenticationStateTask != null)
            {
                var authState = await AuthenticationStateTask;
                CurrentUserName = authState.User.Identity?.Name;
            }
        }
    }
}
额外注意事项
  • 不要在Blazor Server组件中使用IHttpContextAccessor获取用户信息:Blazor Server使用长连接WebSocket通信,HttpContext仅在首次建立连接时存在,后续交互中HttpContext是null或上下文不匹配,官方明确不推荐这种用法,AuthenticationStateProvider是唯一受支持的用户信息获取方式。
  • 如果需要在页面渲染时判断用户认证状态,可以给对应元素加@if (!string.IsNullOrEmpty(CurrentUserName))判断,避免空引用报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:42:31