.NET WebApi HttpClient 未将 Windows 身份验证凭据发送到同一域

Posted

技术标签:

【中文标题】.NET WebApi HttpClient 未将 Windows 身份验证凭据发送到同一域【英文标题】:.NET WebApi HttpClient not sending Windows Authentication credentials to same domain 【发布时间】:2016-08-23 15:40:42 【问题描述】:

我正在使用多个 Intranet API 来尝试构建一些应用程序,这些应用程序具有一些由所有应用程序共享的服务。其中很多服务可以使用 javascript 请求直接从 GUI 调用,但是其中一些服务需要由其他服务器应用程序调用。

所有前端和 API 都使用 Windows 身份验证。现在我已经将它设置为授权任何经过 Windows 身份验证的用户。匿名身份验证已禁用。

我正在使用 HttpClient 从 Web 代码中连接到所需的服务。这是一个例子:

HttpClient client = new HttpClient(new HttpClientHandler()  UseDefaultCredentials = true );
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["OtherServiceUrl"]);

client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));

SomeResponseObject responseObject;
HttpResponseMessage response = client.GetAsync("SomeController").Result;
if (response.IsSuccessStatusCode)

    responseObject = response.Content.ReadAsAsync<SomeResponseObject>().Result;

else

    throw new ApplicationException("API request not successful");

好消息是,当我在本地运行服务时,它工作得很好。坏消息是,当我部署到 IIS 时,对 Web 服务的调用失败并出现未经授权的响应。

经过大量的摆弄,我意识到我唯一一次收到未经授权的响应是目标 API 的域与调用应用程序的域相同。它在我的本地机器上工作,因为 IIS express 为每个应用程序分配了一个新端口。 IIS中出现匹配域的情况是因为我在IIS中将调用应用程序和API都创建为同一个站点下的应用程序,所以这两个应用程序看起来像同一个域中的目录。如果 HttpClient 注意到域匹配,它几乎不会费心从调用 Web 应用程序发送身份验证。

我在同一台服务器上创建了一个新站点,但绑定到不同的端口,然后将 API 放在那里并再次尝试。果然解决了问题,API的请求通过就好了。

我可以放入一堆子域来处理所有这些不同的服务,或者仅仅依靠使用不同的端口来使这些服务的域独一无二,但对我来说,这个限制存在似乎很奇怪.有谁知道我是否可以在处理程序或客户端上设置一个属性,或者我可以做些什么来允许在同一个 IIS 站点上运行的应用程序在使用 Windows 身份验证时通过 HttpClient 相互通信?

谢谢!

根据 Sachin 的建议,我还尝试将其添加到通过 HttpClient 发出 API 请求的应用程序的 webconfig 中:

<system.net>
  <defaultProxy useDefaultCredentials="true" />
</system.net>

还是没有运气。

【问题讨论】:

这可能会有所帮助,请尝试添加配置条目:***.com/questions/299940/… 谢谢萨钦。我尝试将这个添加到 web.config 中,用于向 API 发出请求的 Web 应用程序:&lt;system.net&gt; &lt;defaultProxy useDefaultCredentials="true" /&gt; &lt;/system.net&gt; 不幸的是,我仍然遇到同样的错误。 我也有同样的问题。完全相同。除非我将调用 API 放在不同的端口上,否则我仍然遇到未经授权的问题。除了编辑注册表之外,我希望有一个解决方案。 【参考方案1】:

看看这个:https://support.microsoft.com/en-us/kb/926642

在我的情况下,这与 Windows Server 2012 上的情况相同,但 KB 中的解决方案仍然适用。环回检查将阻止在同一主机上通过 httpClient 发送凭据,这会导致 401。对我来说,唯一的解决方案是方法 2 - 在注册表中设置 DisableLoopbackCheck。我知道这是一项安全“功能”,但这无疑是在经典 Windows 环境中使用现代面向服务架构的障碍。

【讨论】:

谢谢布赖恩!第一种方法对我有用。如果链接失效,解决方案包括添加一个注册表项以允许环回请求。首选方法是将名为 BackConnectionHostNames 的多字符串值添加到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 子项,您要在其自己的行中引用每个 DNS 条目。如果这不起作用,您可以通过将名为 DisableLoopbackCheck 且值为 1 的 DWORD 添加到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa 子项来完全禁用环回检查。

以上是关于.NET WebApi HttpClient 未将 Windows 身份验证凭据发送到同一域的主要内容,如果未能解决你的问题,请参考以下文章

单元测试场景中带有asp.net WebApi的HttpClient

ASP.NET Core HttpClient 请求在 webapi 返回 406 时返回 200

HttpClient.SendAsync() 未将 JSON 作为字符串发送

使用 httpClient.postasync 进行 web api 调用 .net core

利用HttpClient调用WebApi

HttpClient 的 WebAPI 删除列表