为什么 Windows 身份验证是从本地到服务器,而不是从服务器到服务器?
Why is Windows Authentication working from local to server, but not server to server?
我有两个站点,A
和 B
。 A
使用 B
公开的 API,并且 B
需要 Windows 身份验证。两个站点都位于域 D
.
中
API 通过 HttpClient
使用,当站点 A
在本地 运行 时,在我的域帐户下(在域 P
), 访问被授予。在这种情况下,HttpClient
像这样实例化:
using(var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials: true }))
当 A
部署到测试服务器时,上述结果会产生 401 Unauthorized
响应。测试服务器上的应用程序池在域 D
.
中的服务帐户下 运行ning
像这样明确使用该服务帐户时:
var credential = new NetworkCredential("service-account", "password", "D");
var cache = new CredentialCache
{
{
new Uri(apiServerUri), "NTLM", credential
}
};
var handler = new HttpClientHandler
{
Credentials = cache
};
using(var client = new HttpClient(handler))
...
再次在本地 运行ning 站点 A
,访问仍然被授予。当直接通过浏览器访问 API 并指定服务帐户凭据时,也会授予访问权限。日志表明它肯定是用于访问 API.
的服务帐户
将以上部署回测试服务器仍然会导致 401 Unauthorized
。
将站点 A
部署到 IIS 的本地实例,也成功使用了 B
的 API。
运行 本地站点 B
,然后通过本地站点 A
访问它,结果是 401 Unauthorized
.
通过部署 A
的测试服务器上的浏览器访问 API,并指定服务帐户凭据,也会提供 401 Unauthorized
。
我不确定从这里到哪里去 - 我是否遗漏了代码中的某些内容以使其正常工作?还是可能是 IIS 或 AD 问题?
虽然我还没有确切地确定为什么这个解决方法有效,或者是否有更好的方法(因为这感觉很笨拙),以下允许 A
连接到 B
,当两者都位于同一台服务器上时。
站点 B
在 IIS 中进行了额外的主机绑定设置,以监听 localhost:12345
。站点 A
已配置为连接到该端点,而不是站点 B
的域名。身份验证现在可以正常工作。
如果有人能解释为什么会这样,我会很感兴趣 - 我不喜欢 'magic' 修复。
编辑
this kb article 似乎是导致此行为的可能原因。具体来说:
When you use the fully qualified domain name (FQDN) or a custom host
header to browse a local Web site that is hosted on a computer that is
running Microsoft Internet Information Services (IIS) 5.1 or a later
version, you may receive an error message that resembles the
following: HTTP 401.1 - Unauthorized: Logon Failed This issue occurs
when the Web site uses Integrated Authentication and has a name that
is mapped to the local loopback address
和
Therefore, authentication fails if the FQDN or the custom host header that you use does not match the local computer name.
注册表修改在这些服务器上并不是一个真正的选项,所以看起来我们将使用的解决方法。
我有两个站点,A
和 B
。 A
使用 B
公开的 API,并且 B
需要 Windows 身份验证。两个站点都位于域 D
.
API 通过 HttpClient
使用,当站点 A
在本地 运行 时,在我的域帐户下(在域 P
), 访问被授予。在这种情况下,HttpClient
像这样实例化:
using(var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials: true }))
当 A
部署到测试服务器时,上述结果会产生 401 Unauthorized
响应。测试服务器上的应用程序池在域 D
.
像这样明确使用该服务帐户时:
var credential = new NetworkCredential("service-account", "password", "D");
var cache = new CredentialCache
{
{
new Uri(apiServerUri), "NTLM", credential
}
};
var handler = new HttpClientHandler
{
Credentials = cache
};
using(var client = new HttpClient(handler))
...
再次在本地 运行ning 站点 A
,访问仍然被授予。当直接通过浏览器访问 API 并指定服务帐户凭据时,也会授予访问权限。日志表明它肯定是用于访问 API.
将以上部署回测试服务器仍然会导致 401 Unauthorized
。
将站点 A
部署到 IIS 的本地实例,也成功使用了 B
的 API。
运行 本地站点 B
,然后通过本地站点 A
访问它,结果是 401 Unauthorized
.
通过部署 A
的测试服务器上的浏览器访问 API,并指定服务帐户凭据,也会提供 401 Unauthorized
。
我不确定从这里到哪里去 - 我是否遗漏了代码中的某些内容以使其正常工作?还是可能是 IIS 或 AD 问题?
虽然我还没有确切地确定为什么这个解决方法有效,或者是否有更好的方法(因为这感觉很笨拙),以下允许 A
连接到 B
,当两者都位于同一台服务器上时。
站点 B
在 IIS 中进行了额外的主机绑定设置,以监听 localhost:12345
。站点 A
已配置为连接到该端点,而不是站点 B
的域名。身份验证现在可以正常工作。
如果有人能解释为什么会这样,我会很感兴趣 - 我不喜欢 'magic' 修复。
编辑 this kb article 似乎是导致此行为的可能原因。具体来说:
When you use the fully qualified domain name (FQDN) or a custom host header to browse a local Web site that is hosted on a computer that is running Microsoft Internet Information Services (IIS) 5.1 or a later version, you may receive an error message that resembles the following: HTTP 401.1 - Unauthorized: Logon Failed This issue occurs when the Web site uses Integrated Authentication and has a name that is mapped to the local loopback address
和
Therefore, authentication fails if the FQDN or the custom host header that you use does not match the local computer name.
注册表修改在这些服务器上并不是一个真正的选项,所以看起来我们将使用的解决方法。