如何在部署于IIS的Blazor Server应用中获取AD用户ID?
解决Blazor Server部署IIS后获取AD用户身份并访问数据库的问题
一、项目内核心配置修正
Blazor Server基于SignalR,认证配置和传统ASP.NET有所区别,先确保项目代码配置正确:
- 在
Program.cs中添加Windows认证和授权服务:builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); builder.Services.AddAuthorization(options => { // 强制所有组件都需要认证 options.FallbackPolicy = options.DefaultPolicy; }); // 注册HttpContextAccessor(可选,用于部分服务类场景) builder.Services.AddHttpContextAccessor(); - 确保中间件顺序正确,认证要在授权之前:
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管理员配合的配置(你可告知管理员)
- 站点认证设置:确保目标站点已禁用「匿名认证」,启用「Windows认证」和「ASP.NET模拟」(并非仅添加web.config配置)。
- 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> - Kerberos委派配置:如果站点使用域名访问,需要管理员为IIS应用池账号注册SPN(服务主体名称),否则可能出现身份传递失败的问题。
四、数据库访问的关键注意事项
- 数据库连接字符串必须使用
Integrated Security=True,不要指定用户名和密码,这样会自动使用当前模拟的AD用户身份连接数据库。 - 确保该AD用户具有数据库的访问权限(读取/写入等)。
五、排查要点
- 确认客户端浏览器是否自动发送AD凭据:IE/Edge默认支持,Chrome需将站点加入「本地Intranet」区域,或在浏览器设置中允许Windows认证。
- 检查SignalR连接请求:在浏览器开发者工具的「网络」标签中,查看SignalR的启动请求,确认请求头包含Authorization相关信息。
内容的提问来源于stack exchange,提问作者CsharpSqlGuy
相关产品推荐
相关产品推荐

