如何在ASP.NET Core 6 MVC应用中获取客户端用户名
我正在用.NET 6.0和React重构内网系统,需要获取AD域用户名来查询用户数据。环境是Active Directory域,采用SSO认证,浏览器应该自动传递用户信息到API。在.NET Framework 4.5里可以通过HttpContext.Current.User.Identity.Name拿到用户名,但.NET 6里尝试注入IHttpContextAccessor后,User.Identity始终返回null。
我已经在Program.cs中添加了builder.Services.AddHttpContextAccessor();,Web.Config里认证类型设为Windows,开发环境用IISExpress,两台机器(VPN/内网直连)测试结果一致。之后按照配置了Negotiate认证,但还是无法获取用户名。
更新后的代码:
SitemapController.cs
namespace webapi.Controllers { [ApiController] [Route("[controller]")] public class SitemapController : Controller { [HttpGet] public string Get() { Console.WriteLine("Sitemap Test"); var user = this.User.Identity.Name; var siteMap = Data.Sitemap(); return siteMap; } } }
Program.cs
using Microsoft.AspNetCore.Authentication.Negotiate; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } //app.UseHttpsRedirection(); app.UseAuthentication(); //app.UseAuthorization(); app.MapControllers(); app.Run();
以下是关键的排查和修复步骤:
1. 启用IIS Express的Windows身份验证
开发环境下,确保IIS Express已启用Windows身份验证并禁用匿名身份验证:
- 右键项目 → 属性 → 调试 → 找到"IIS Express"区域
- 勾选"启用Windows身份验证",取消勾选"启用匿名身份验证"
2. 启用Authorization中间件
你的Program.cs中注释掉了app.UseAuthorization();,这会导致认证后的用户信息无法被正确识别。取消注释该行,保证中间件顺序正确:
app.UseAuthentication(); app.UseAuthorization(); // 取消注释此代码
3. 给控制器添加授权属性
在控制器或Action上添加[Authorize]属性,强制要求用户经过认证才能访问:
[ApiController] [Route("[controller]")] [Authorize] // 添加该属性 public class SitemapController : Controller { // ... 其他代码 }
4. 检查浏览器自动登录设置
确保浏览器允许自动使用当前AD域账户进行NTLM/Kerberos认证:
- Chrome/Edge:地址栏输入
chrome://settings/content/passwords开启"自动登录";通过chrome://net-internals/#auth确认未阻止站点认证请求 - IE:Internet选项 → 安全 → 本地Intranet → 自定义级别 → 勾选"自动登录到Intranet区域"
5. 调试Negotiate认证流程
可以在Negotiate配置中添加事件回调,打印调试信息确认用户是否被正确认证:
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(options => { options.Events = new NegotiateEvents { OnAuthenticated = context => { Console.WriteLine($"Authenticated user: {context.Principal?.Identity?.Name}"); return Task.CompletedTask; } }; });
6. 验证Web.Config配置(若存在)
如果项目包含Web.Config,确保以下配置正确:
<system.webServer> <security> <authentication> <anonymousAuthentication enabled="false" /> <windowsAuthentication enabled="true" /> </authentication> </security> </system.webServer>
完成以上步骤后重启项目,即可通过this.User.Identity.Name获取AD域用户名。
内容的提问来源于stack exchange,提问作者Geoff

