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

.NET 9 Blazor Server配置Windows AD认证后无法获取用户名与角色

.NET 9 Blazor Server Windows AD认证:用户名Null与角色获取问题解决

我用.NET 9 Blazor Web App模板创建了Server渲染模式的Blazor Server项目,想配置Windows AD认证,但用户页面始终输出null用户名,也无法获取角色(已加入域)。用var user = System.Security.Principal.WindowsIdentity.GetCurrent().Name;能拿到用户名,但还需要获取用户角色。请问当前代码缺少什么配置?

相关代码

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", policy =>
        policy.RequireRole("DOMAIN\\AdminGroup"));
});

// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

User页面

@page "/user"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h3>User Information</h3>

@if (user != null)
{
    <p>Username: @user.Identity.Name</p>
    <ul>
        @foreach (var claim in user.Claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}
else
{
    <p>Loading...</p>
}

@code {
    private ClaimsPrincipal? user;

    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        user = authState.User;
        var username = user.Identity?.Name;
        var roles = user.Claims.Where(c => c.Type == ClaimTypes.Role);
        Console.WriteLine("Roles: " + string.Join(", ", roles.Select(r => r.Value)));
    }
}

LaunchSettings.json

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:28505",
      "sslPort": 44325
    }
  },
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5050",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "windowsAuthentication": true,
      "anonymousAuthentication": false
    },
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7150;http://localhost:5050",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "windowsAuthentication": true,
      "anonymousAuthentication": false
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "windowsAuthentication": true,
      "anonymousAuthentication": false
    }
  }
}

问题截图

显示Null用户名的页面


解决配置

你的代码有两处关键缺失,导致无法通过Blazor的AuthenticationStateProvider正确获取AD用户身份和角色:

1. 启用Windows身份验证的声明/角色转换

默认的Negotiate认证不会自动将AD用户的组转换为ClaimTypes.Role声明,需要添加AddWindowsClaimsPrincipalHandler来处理AD角色映射。修改Program.cs中的认证配置:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate()
    .AddWindowsClaimsPrincipalHandler(options =>
    {
        options.IncludeGroups = true; // 自动将AD组转换为Role声明
    });

如果需要自定义处理逻辑,也可以通过事件手动添加角色声明:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate(options =>
    {
        options.Events = new NegotiateEvents
        {
            OnAuthenticated = context =>
            {
                var windowsIdentity = context.Principal.Identity as WindowsIdentity;
                if (windowsIdentity != null)
                {
                    // 将AD用户所属组转换为Role声明
                    var groupClaims = windowsIdentity.Groups.Translate(typeof(NTAccount))
                        .Select(group => new Claim(ClaimTypes.Role, group.Value));
                    context.Principal.AddIdentity(new ClaimsIdentity(groupClaims));
                }
                return Task.CompletedTask;
            }
        };
    })
    .AddWindowsClaimsPrincipalHandler();

2. 为组件添加授权特性

你的User页面没有启用授权,Blazor不会强制触发认证流程,导致AuthenticationStateProvider返回匿名用户,所以user.Identity.Name为null。在页面顶部添加授权特性:

@page "/user"
@attribute [Authorize] // 添加这行启用授权
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

或者在@code块上添加[Authorize]:

@code {
    [Authorize]
    private ClaimsPrincipal? user;

    // 其余代码不变
}

验证配置顺序

你的Program.cs中UseAuthentication()和UseAuthorization()的顺序是正确的,必须在MapRazorComponents之前调用,这部分无需修改。

额外提示

  • 确保应用运行账号有权限查询AD用户组信息(开发环境用当前登录账号,已加入域通常没问题)。
  • 若仍有问题,可先在API端点中通过HttpContext.User验证是否获取到正确身份,再排查Blazor认证状态传递问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:19:51