如何在ASP.NET WebApi POST请求中转发Windows身份?NTLM可行吗?
解决方案:Windows身份验证转发到旧ASP.NET API
关于NTLM的限制
NTLM无法实现身份转发,这是由它的挑战-响应机制决定的:NTLM验证仅在客户端与直接对接的服务器之间完成,服务器无法获取可转发的用户凭证,以此向其他服务发起验证请求。如果要实现身份转发,必须切换到Kerberos身份验证。
具体实现步骤
1. 配置Kerberos环境
- 确保包装器、旧API服务器都加入同一Active Directory域(或信任域)
- 为旧API注册服务主体名称(SPN):
以域管理员身份在命令行执行:
替换setspn -S HTTP/oldapi.yourdomain.com DOMAIN\OldApiAppPoolAccountoldapi.yourdomain.com为旧API的域名,DOMAIN\OldApiAppPoolAccount为旧API应用池运行的域账户 - 为包装器的应用池账户配置委派权限:
在AD用户和计算机中找到包装器的应用池账户,打开属性→委派→选择「信任此用户委派到指定服务」,添加刚才注册的旧API的SPN
2. 代码层面的正确配置
不要依赖DefaultCredentials的通用设置,确保代码中明确使用当前请求的用户身份:
ASP.NET Framework示例
using System.Net.Http; using System.Threading.Tasks; using System.Web; public async Task<string> CallOldApi() { // 使用当前请求的用户身份发起请求 var handler = new HttpClientHandler { UseDefaultCredentials = true, // 关闭自动重定向,避免跳转时丢失Kerberos票据 AllowAutoRedirect = false }; using (var client = new HttpClient(handler)) { var response = await client.GetAsync("http://oldapi.yourdomain.com/api/target"); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } }
ASP.NET Core示例
using System.Net.Http; using Microsoft.AspNetCore.Http; public async Task<string> CallOldApi(HttpContext httpContext) { var handler = new HttpClientHandler { UseDefaultCredentials = true, AllowAutoRedirect = false }; using var client = new HttpClient(handler); var response = await client.GetAsync("http://oldapi.yourdomain.com/api/target"); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); }
3. IIS站点配置检查
- 包装器和旧API的IIS站点均启用Windows身份验证,禁用匿名身份验证
- 包装器的应用池必须使用域账户运行(本地系统/本地服务账户无法使用Kerberos委派)
- 在IIS身份验证设置中,确保Kerberos优先级高于NTLM(可通过调整提供程序顺序实现)
4. 问题排查技巧
- 在包装器服务器上执行
klist get HTTP/oldapi.yourdomain.com,检查是否能获取到Kerberos服务票据 - 查看IIS日志中的
cs-auth-type字段,确认身份验证类型是Kerberos而非NTLM - 检查事件查看器的「系统」日志,查找Kerberos相关错误(如SPN未注册、委派权限不足)
内容的提问来源于stack exchange,提问作者Waymaker
相关产品推荐
相关产品推荐

