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

Blazor Server中AuthorizationHandlerContext.User.Identity.Name返回null问题

Blazor Server Windows认证+自定义数据库授权问题排查方案

一、先检查中间件配置顺序(核心)

Blazor Server中认证和授权中间件的顺序绝对不能错,必须先认证再授权,同时要确保Windows认证正确注册:

// 1. 注册Windows认证(Negotiate方案)
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();

// 2. 注册自定义授权策略和处理类
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("EmpRights", policy =>
        policy.Requirements.Add(new AuthorizedEmpsRequirement()));
});
// 务必把授权处理类注册为Scoped
builder.Services.AddScoped<IAuthorizationHandler, AuthorizedEmpsHandler>();

// 3. 配置Blazor Server,确保关联认证状态
builder.Services.AddServerSideBlazor(options =>
{
    options.DetailedErrors = true; // 开发环境开启,方便看错误详情
})
.AddAuthenticationStateProvider<RevalidatingServerAuthenticationStateProvider>();

// 4. 中间件顺序:先认证,再授权,最后映射Blazor端点
app.UseAuthentication();
app.UseAuthorization();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

二、修正授权处理类的实现

你的问题中context.User.Identity.Name为null,大概率是处理类中没先判断用户是否已认证,或者数据库查询逻辑阻塞导致上下文丢失。调整后的处理类示例:

public class AuthorizedEmpsRequirement : IAuthorizationRequirement { }

public class AuthorizedEmpsHandler : AuthorizationHandler<AuthorizedEmpsRequirement>
{
    private readonly IConfiguration _configuration;

    public AuthorizedEmpsHandler(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthorizedEmpsRequirement requirement)
    {
        // 第一步:先确认用户已完成Windows认证
        if (!context.User.Identity.IsAuthenticated)
        {
            context.Fail();
            return;
        }

        // 第二步:获取用户名,为空直接拒绝
        var userName = context.User.Identity.Name;
        if (string.IsNullOrWhiteSpace(userName))
        {
            context.Fail();
            return;
        }

        // 第三步:异步从数据库查询授权名单(必须用异步,避免阻塞Blazor上下文)
        var authorizedList = await GetAuthorizedUsersFromDb();
        if (authorizedList.Contains(userName, StringComparer.OrdinalIgnoreCase))
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
    }

    private async Task<List<string>> GetAuthorizedUsersFromDb()
    {
        var connString = _configuration.GetConnectionString("YourDbConnectionName");
        var userList = new List<string>();

        using var conn = new SqlConnection(connString);
        await conn.OpenAsync();
        using var cmd = new SqlCommand("SELECT UserName FROM AuthorizedEmployeesTable", conn);
        using var reader = await cmd.ExecuteReaderAsync();
        
        while (await reader.ReadAsync())
        {
            userList.Add(reader.GetString(0));
        }

        return userList;
    }
}

三、检查的正确用法

确保组件中正确区分Authorized和NotAuthorized模板,并且从context中获取用户信息:

<AuthorizeView Policy="EmpRights">
    <Authorized>
        <div>
            <p>当前登录用户:@context.User.Identity.Name</p>
            <!-- 你的业务内容 -->
        </div>
    </Authorized>
    <NotAuthorized>
        <p>抱歉,你没有访问权限</p>
    </NotAuthorized>
    <Authenticating>
        <p>正在验证身份...</p>
    </Authenticating>
</AuthorizeView>

四、额外排查点

  1. 启用Windows认证:

    • 开发环境下,检查launchSettings.json中iisSettings.windowsAuthentication是否为true,anonymousAuthentication是否为false
    • Kestrel部署的话,要在ConfigureKestrel中启用Windows认证:
      builder.WebHost.ConfigureKestrel(options =>
      {
          options.ListenAnyIP(5001, listenOptions =>
          {
              listenOptions.UseHttps();
              listenOptions.UseWindowsAuthentication();
          });
      });
      
  2. 避免同步阻塞操作:
    你的AuthorizedEmployees方法如果是同步的,可能会导致Blazor的AuthenticationState上下文丢失,一定要改成异步实现(如上面示例中的GetAuthorizedUsersFromDb)。

  3. 验证DI注册:
    确保AuthorizedEmpsHandler已经正确注册到DI容器,没有遗漏builder.Services.AddScoped<IAuthorizationHandler, AuthorizedEmpsHandler>();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:37:44