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

如何在部署于IIS的Blazor Server应用中获取AD用户ID?

解决Blazor Server部署IIS后获取AD用户身份并访问数据库的问题

一、项目内核心配置修正

Blazor Server基于SignalR,认证配置和传统ASP.NET有所区别,先确保项目代码配置正确:

  1. 在Program.cs中添加Windows认证和授权服务:
    builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate();
    builder.Services.AddAuthorization(options =>
    {
        // 强制所有组件都需要认证
        options.FallbackPolicy = options.DefaultPolicy;
    });
    // 注册HttpContextAccessor(可选,用于部分服务类场景)
    builder.Services.AddHttpContextAccessor();
    
  2. 确保中间件顺序正确,认证要在授权之前:
    app.UseAuthentication();
    app.UseAuthorization();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    

二、正确获取AD用户身份的方式

不要使用WindowsIdentity.GetCurrent()或Thread.CurrentPrincipal——Blazor Server的线程模型会导致这些API获取到的是IIS应用池线程身份,而非访问用户。正确方式如下:

1. 在Blazor组件中获取身份

注入AuthenticationStateProvider,通过异步方法获取用户身份:

@inject AuthenticationStateProvider AuthStateProvider

<p>当前AD用户:@AdUserId</p>

@code {
    private string? AdUserId;

    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;
        
        if (user.Identity is WindowsIdentity windowsIdentity && user.Identity.IsAuthenticated)
        {
            AdUserId = windowsIdentity.Name;
            // 在此处模拟用户身份执行数据库操作
            using (windowsIdentity.Impersonate())
            {
                // 调用数据库访问方法,此时会使用当前AD用户身份
                await LoadDataFromDb();
            }
        }
    }

    private async Task LoadDataFromDb()
    {
        // 数据库操作逻辑,例如EF Core查询
        using var dbContext = new YourDbContext();
        var data = await dbContext.YourEntities.ToListAsync();
    }
}

2. 在服务类中获取身份

如果需要在后台服务中使用,建议通过组件传递WindowsIdentity,或注入IHttpContextAccessor(注意:HttpContext仅在初始请求和SignalR连接建立阶段有效,不适合长期持有):

public class YourDataService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public YourDataService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<List<YourEntity>> GetData()
    {
        var context = _httpContextAccessor.HttpContext;
        if (context?.User.Identity is WindowsIdentity windowsIdentity && windowsIdentity.IsAuthenticated)
        {
            using (windowsIdentity.Impersonate())
            {
                using var dbContext = new YourDbContext();
                return await dbContext.YourEntities.ToListAsync();
            }
        }
        return new List<YourEntity>();
    }
}

三、需要IIS管理员配合的配置(你可告知管理员)

  1. 站点认证设置:确保目标站点已禁用「匿名认证」,启用「Windows认证」和「ASP.NET模拟」(并非仅添加web.config配置)。
  2. web.config补充配置:
    <system.web>
        <authentication mode="Windows"/>
        <identity impersonate="true"/>
    </system.web>
    <system.webServer>
        <security>
            <authentication>
                <anonymousAuthentication enabled="false"/>
                <windowsAuthentication enabled="true"/>
            </authentication>
        </security>
    </system.webServer>
    
  3. Kerberos委派配置:如果站点使用域名访问,需要管理员为IIS应用池账号注册SPN(服务主体名称),否则可能出现身份传递失败的问题。

四、数据库访问的关键注意事项

  • 数据库连接字符串必须使用Integrated Security=True,不要指定用户名和密码,这样会自动使用当前模拟的AD用户身份连接数据库。
  • 确保该AD用户具有数据库的访问权限(读取/写入等)。

五、排查要点

  • 确认客户端浏览器是否自动发送AD凭据:IE/Edge默认支持,Chrome需将站点加入「本地Intranet」区域,或在浏览器设置中允许Windows认证。
  • 检查SignalR连接请求:在浏览器开发者工具的「网络」标签中,查看SignalR的启动请求,确认请求头包含Authorization相关信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:12:23