Blazor Server升级.NET6后Windows认证获取客户端用户名异常
问题分析与解决方案
核心问题根源
从.NET Core 3.1升级到.NET 6后,Windows认证的配置逻辑发生了变化,旧版的web.config配置方式不再适配,导致客户端身份无法正确传递,程序默认使用了服务器应用池的运行账号。同时升级后登录弹窗消失,也是因为认证流程未正确配置,浏览器无法触发身份验证请求。
解决方案步骤
1. 修正Program.cs中的认证配置
.NET 6采用顶级语句配置,需在Program.cs中显式注册Windows认证服务,并确保中间件顺序正确:
var builder = WebApplication.CreateBuilder(args); // 注册Windows认证(使用Negotiate协议,支持NTLM和Kerberos) builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); // 设置默认授权策略 builder.Services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; }); // 注册Blazor Server服务及SignalR配置 builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor() .AddHubOptions(options => { options.MaximumReceiveMessageSize = 1024 * 1024; }); // 注册HttpContextAccessor(确保已注入到组件中) builder.Services.AddHttpContextAccessor(); var app = builder.Build(); // 中间件顺序:认证必须在路由之前 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // 启用认证和授权中间件 app.UseAuthentication(); app.UseAuthorization(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Run();
2. 处理web.config配置报错(0x80070021)
报错原因是IIS默认锁定了Windows认证的配置节,不能直接在web.config中修改。解决方式:
- 移除手动添加的认证配置:删除web.config中
<authentication>或<authorization>相关节点,由.NET 6自动生成正确配置。 - 解锁IIS配置节:
- 打开IIS管理器,选择服务器节点,双击「功能委派」
- 找到「身份验证 - Windows」,将委派模式改为「可读/可写」
- 或执行命令行:
appcmd unlock config /section:system.webServer/security/authentication/windowsAuthentication
- 可选:强制IIS启用Windows认证:在web.config中添加(解锁后生效):
<system.webServer> <security> <authentication> <anonymousAuthentication enabled="false" /> <windowsAuthentication enabled="true" /> </authentication> </security> </system.webServer>
3. 修复用户名读取逻辑
原代码中固定移除前5个字符的方式不可靠,改用分割域名和用户名的通用写法:
public void ReadUserName() { var fullUserName = httpContextAccessor.HttpContext.User.Identity.Name; if (!string.IsNullOrEmpty(fullUserName)) { // 按反斜杠分割域名与用户名 var userNameParts = fullUserName.Split('\\'); TagService.LoginUserName = userNameParts.Length > 1 ? userNameParts[1] : fullUserName; } else { TagService.LoginUserName = "Unknown User"; } using (StreamWriter sw = File.AppendText(log_path)) { sw.WriteLine($"Logged in user : {TagService.LoginUserName} {DateTime.Now}"); } }
同时确保组件中已注入IHttpContextAccessor:
@inject IHttpContextAccessor httpContextAccessor
4. 恢复登录弹窗提示
如果浏览器不再弹出身份验证窗口,需检查客户端浏览器设置:
- Edge/IE:设置 → 隐私和安全 → 安全 → 本地Intranet → 自定义级别 → 用户身份验证 → 选择「提示输入用户名和密码」
- Chrome:设置 → 隐私和安全 → 安全 → 本地Intranet → 添加你的网站域名,然后配置自动登录策略为「每次询问」
5. 检查应用池身份
确保应用池身份使用「NetworkService」而非本地系统账号,避免身份模拟异常。
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

