WCF 客户端的默认默认 SPN 是“host/myhostname”还是“http/myhostname”?为什么?
Is the default default SPN for a WCF Client `host/myhostname` or `http/myhostname` and why?
由于 this question,未指定 identity
时的默认行为是 host/myhostname
。
然而这似乎并不完全正确。
我有一个 SOAP WCF 服务(它是一个 Dynamics NAV Web 服务,但这对以下内容无关紧要,因为这个问题完全是关于客户端的角度),如果我没有指定任何身份,它就不起作用。
服务器实际上运行在域用户帐户下。
host/myhostname
已指定但不是针对此用户帐户,仅针对计算机帐户。
http/myhostname
已为此域用户帐户指定。
让我们来看看三种情况:
未指定身份
我使用以下代码创建 EndpointAddress
:
new EndpointAddress(new Uri(endpoint))
在这种情况下,会发生以下情况:
- HTTP POST 没有
Authorization
header.
- 响应
WWW-Authenticate: Negotiate
。
- HTTP POST 与
Authorization: Negotiate XXX
header。 XXX
是 1584 个 BASE64 编码字节,以 96 130 6
开头。我在其中找不到任何可读的 ASCII。
- 响应
Authorization: Negotiate XXX
header。 XXX
是 126 个 BASE64 编码字节。我在其中找不到任何可读的 ASCII。
- HTTP POST 与
Authorization: Negotiate XXX
header。 XXX
是 1527 个 BASE64 编码字节。我在其中找不到任何可读的 ASCII。
- 响应
WWW-Authenticate: Negotiate XXX
header。 XXX
是 113 个 BASE64 编码字节。我在其中找不到任何可读的 ASCII。
- 此时客户端抛出异常。内部异常消息是
The target principal name is incorrect
.
手动将身份设置为 host/myhostname
或错误的字符串。
我使用以下代码创建 EndpointAddress:
var identity = EndpointIdentity.CreateSpnIdentity(@"host/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
如果 host/myhostname
是默认设置,上面的代码将明确指定此默认设置。所以我会 期待相同的行为 。但这有效。看来我又回到了 NTLM。所以一定有区别.
事情是这样的:
- HTTP POST 没有
Authorization
header.
- 响应
WWW-Authenticate: Negotiate
。
- HTTP POST with
Authorization: Negotiate XXX
其中 XXX 是 40 个 BASE64 编码字节。第一个字节是 ASCII 字母 NTLMSSP
.
- 响应
WWW-Authenticate: Negotiate XXX
,其中 XXX 是 270 个 BASE64 编码字节。第一个字节是 ASCII 字母 NTLMSSP
。此外,FQDN 似乎被编码为 ASCII。
- HTTP POST with
Authorization: Negotiate XXX
,其中 XXX 是 590 个 BASE64 编码字节。这次没有 ASCII 字母。
- 使用负载响应。
一个有趣的事实:如果我将身份指定给任何错误的字符串,我都会有完全相同的行为。因此,例如,如果我使用此代码指定 EndpointAddress
:
var identity = EndpointIdentity.CreateSpnIdentity(@"thisIsTotallyWrongLoremIpsum");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
我也得到了上面的行为,回退到 NTLM。
我正确地将身份设置为 http/myhostname
现在,当我将 SPN 指定为 http/myhostname
时,它已设置并且似乎是正确的选择,因为 RFC 4559 它有效。这是配置:
var identity = EndpointIdentity.CreateSpnIdentity(@"http/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
事情是这样的:
- HTTP POST 没有
Authorization
header.
- 响应
WWW-Authenticate: Negotiate
。
- HTTP POST 与
Authorization: Negotiate XXX
header。 XXX 是 1580 个 BASE64 编码字节。没有 ASCI 标志。
- 使用负载响应。
这个问题不是关于让它工作的热点,而是关于理解。
令我困惑的是第一个和第二个例子之间的区别。我的想法是:
- 如果默认身份是
host/myhostname
,
- 手动指定身份到
host/myhostname
、 应该没有什么区别
- 但还是有区别的
- 所以这不能是默认身份。
所以我的问题是
- 实际的默认行为是什么,
- 为什么
http/myhostname
由于 RFC4559 而未被选为默认 SPN?
And/or我是不是理解错了什么?
问题陈述末尾提出了两个具体问题;在下面列出它们。
问。 1)实际的默认行为是什么?
一个。如果未指定身份,并且客户端凭据类型为 Windows,则默认值为 SPN,其值设置为服务端点地址的主机名部分,前缀为 "host/" 文字。此设置利用 Windows Kerberos 安全性,如果该服务是 运行 在一个系统帐户下或在具有关联 SPN 名称的域帐户下,并且计算机是其中一个域的成员Active Directory 环境。
问。 2) 为什么 http/myhostname 由于 RFC4559 而没有被选为默认的 SPN?
一个。使用 Web 浏览器,您将连接为 http/myhostname。但是对于 WCF 客户端,默认情况下是按照上述方式连接为 host/myhostname。在您将标识设置为 host/myhostname.
的场景 #2 下,它肯定会连接到 host/myhostname
以上Q1和Q2参考:Service Identity and Authentication
评论:回退到 NTLM 的原因有很多。解决这个问题的方法是了解 Kerberos 失败的原因 - SPN 问题是主要原因。诊断 SPN 问题的重要参考是 Blog of Brian Murphy-Booth - The biggest mistake: ServicePrincipalName’s.
看了Brian Murphy的博客,后来被原提问者发现,在问题场景中,使用了一个端口。 "The port is not used when the SPN is automatically determined. So http://foo.example.com:1234 leads to host/foo.example.com as SPN. And when the SPN does not exist it does fall back to NTLM and when the SPN does exist but not for the right user it throws the The target principal name is incorrect exception."
由于 this question,未指定 identity
时的默认行为是 host/myhostname
。
然而这似乎并不完全正确。
我有一个 SOAP WCF 服务(它是一个 Dynamics NAV Web 服务,但这对以下内容无关紧要,因为这个问题完全是关于客户端的角度),如果我没有指定任何身份,它就不起作用。
服务器实际上运行在域用户帐户下。
host/myhostname
已指定但不是针对此用户帐户,仅针对计算机帐户。
http/myhostname
已为此域用户帐户指定。
让我们来看看三种情况:
未指定身份
我使用以下代码创建 EndpointAddress
:
new EndpointAddress(new Uri(endpoint))
在这种情况下,会发生以下情况:
- HTTP POST 没有
Authorization
header. - 响应
WWW-Authenticate: Negotiate
。 - HTTP POST 与
Authorization: Negotiate XXX
header。XXX
是 1584 个 BASE64 编码字节,以96 130 6
开头。我在其中找不到任何可读的 ASCII。 - 响应
Authorization: Negotiate XXX
header。XXX
是 126 个 BASE64 编码字节。我在其中找不到任何可读的 ASCII。 - HTTP POST 与
Authorization: Negotiate XXX
header。XXX
是 1527 个 BASE64 编码字节。我在其中找不到任何可读的 ASCII。 - 响应
WWW-Authenticate: Negotiate XXX
header。XXX
是 113 个 BASE64 编码字节。我在其中找不到任何可读的 ASCII。 - 此时客户端抛出异常。内部异常消息是
The target principal name is incorrect
.
手动将身份设置为 host/myhostname
或错误的字符串。
我使用以下代码创建 EndpointAddress:
var identity = EndpointIdentity.CreateSpnIdentity(@"host/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
如果 host/myhostname
是默认设置,上面的代码将明确指定此默认设置。所以我会 期待相同的行为 。但这有效。看来我又回到了 NTLM。所以一定有区别.
事情是这样的:
- HTTP POST 没有
Authorization
header. - 响应
WWW-Authenticate: Negotiate
。 - HTTP POST with
Authorization: Negotiate XXX
其中 XXX 是 40 个 BASE64 编码字节。第一个字节是 ASCII 字母NTLMSSP
. - 响应
WWW-Authenticate: Negotiate XXX
,其中 XXX 是 270 个 BASE64 编码字节。第一个字节是 ASCII 字母NTLMSSP
。此外,FQDN 似乎被编码为 ASCII。 - HTTP POST with
Authorization: Negotiate XXX
,其中 XXX 是 590 个 BASE64 编码字节。这次没有 ASCII 字母。 - 使用负载响应。
一个有趣的事实:如果我将身份指定给任何错误的字符串,我都会有完全相同的行为。因此,例如,如果我使用此代码指定 EndpointAddress
:
var identity = EndpointIdentity.CreateSpnIdentity(@"thisIsTotallyWrongLoremIpsum");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
我也得到了上面的行为,回退到 NTLM。
我正确地将身份设置为 http/myhostname
现在,当我将 SPN 指定为 http/myhostname
时,它已设置并且似乎是正确的选择,因为 RFC 4559 它有效。这是配置:
var identity = EndpointIdentity.CreateSpnIdentity(@"http/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
事情是这样的:
- HTTP POST 没有
Authorization
header. - 响应
WWW-Authenticate: Negotiate
。 - HTTP POST 与
Authorization: Negotiate XXX
header。 XXX 是 1580 个 BASE64 编码字节。没有 ASCI 标志。 - 使用负载响应。
这个问题不是关于让它工作的热点,而是关于理解。 令我困惑的是第一个和第二个例子之间的区别。我的想法是:
- 如果默认身份是
host/myhostname
, - 手动指定身份到
host/myhostname
、 应该没有什么区别
- 但还是有区别的
- 所以这不能是默认身份。
所以我的问题是
- 实际的默认行为是什么,
- 为什么
http/myhostname
由于 RFC4559 而未被选为默认 SPN?
And/or我是不是理解错了什么?
问题陈述末尾提出了两个具体问题;在下面列出它们。
问。 1)实际的默认行为是什么?
一个。如果未指定身份,并且客户端凭据类型为 Windows,则默认值为 SPN,其值设置为服务端点地址的主机名部分,前缀为 "host/" 文字。此设置利用 Windows Kerberos 安全性,如果该服务是 运行 在一个系统帐户下或在具有关联 SPN 名称的域帐户下,并且计算机是其中一个域的成员Active Directory 环境。
问。 2) 为什么 http/myhostname 由于 RFC4559 而没有被选为默认的 SPN?
一个。使用 Web 浏览器,您将连接为 http/myhostname。但是对于 WCF 客户端,默认情况下是按照上述方式连接为 host/myhostname。在您将标识设置为 host/myhostname.
的场景 #2 下,它肯定会连接到 host/myhostname以上Q1和Q2参考:Service Identity and Authentication
评论:回退到 NTLM 的原因有很多。解决这个问题的方法是了解 Kerberos 失败的原因 - SPN 问题是主要原因。诊断 SPN 问题的重要参考是 Blog of Brian Murphy-Booth - The biggest mistake: ServicePrincipalName’s.
看了Brian Murphy的博客,后来被原提问者发现,在问题场景中,使用了一个端口。 "The port is not used when the SPN is automatically determined. So http://foo.example.com:1234 leads to host/foo.example.com as SPN. And when the SPN does not exist it does fall back to NTLM and when the SPN does exist but not for the right user it throws the The target principal name is incorrect exception."