是WCF客户端`host / myhostname`或`http / myhostname`的默认默认SPN,为什么?

时间:2016-12-02 12:57:50

标签: wcf kerberos spnego spn negotiate

由于this question未指定identity时的默认行为是host/myhostname

然而,这似乎并非完全正确。

我有一个SOAP WCF服务(它是一个Dynamics NAV Web服务,但这对于以下内容无关紧要,因为问题完全是关于客户端的观点),如果我没有指定任何身份,则无效。

服务器实际上是在域用户帐户下运行。 已指定host/myhostname但不是此用户帐户,仅适用于计算机帐户。 为此域用户帐户指定了http/myhostname

让我们看看三种情况:

未指定身份

我使用以下代码创建EndpointAddress

new EndpointAddress(new Uri(endpoint))

在这种情况下,会发生以下情况:

  • 没有Authorization标题的HTTP POST。
  • 使用WWW-Authenticate: Negotiate回复。
  • 带有Authorization: Negotiate XXX标头的HTTP POST。 XXX是1584个BASE64编码字节,以96 130 6开头。我在其中找不到任何可读的ASCII。
  • 使用Authorization: Negotiate XXX标头回复。 XXX是126 BASE64编码的字节。我在其中找不到任何可读的ASCII。
  • 带有Authorization: Negotiate XXX标头的HTTP POST。 XXX是1527个BASE64编码的字节。我在其中找不到任何可读的ASCII。
  • 使用WWW-Authenticate: Negotiate XXX标头回复。 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。所以必须是差异

这是最新发生的事情:

  • 没有Authorization标题的HTTP POST。
  • 使用WWW-Authenticate: Negotiate回复。
  • 带有Authorization: Negotiate XXX的HTTP POST,其中XXX是40个BASE64编码字节。第一个字节是ASCII字母NTLMSSP
  • WWW-Authenticate: Negotiate XXX的响应,其中XXX是270 BASE64编码的字节。第一个字节是ASCII字母NTLMSSP。此外,FQDN似乎编码为ASCII。
  • 带有Authorization: Negotiate XXX的HTTP POST,其中XXX是590 BASE64编码的字节。这次没有ASCII字母。
  • 对有效负载的回应。

一个有趣的事实:如果我为任何错误的String指定了标识,我就会有完全相同的行为。例如,如果我使用以下代码指定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);

这就是发生的事情:

  • 没有Authorization标题的HTTP POST。
  • 使用WWW-Authenticate: Negotiate回复。
  • 带有Authorization: Negotiate XXX标头的HTTP POST。 XXX是1580 BASE64编码的字节。没有ASCI标志。
  • 对有效负载的回应。

这个问题并不是关于让它发挥作用而是关于理解的热点。 让我困惑的是第一个和第二个例子之间的区别。我的想法是:

  1. 如果默认标识为host/myhostname
  2. 手动指定host/myhostname
  3. 的身份应该没有区别
  4. 但存在差异
  5. 所以这不能是默认身份。
  6. 所以我的问题是

    1. 实际的默认行为是什么,
    2. 为什么http/myhostname未被选为默认SPN,因为RFC4559应该如此?
    3. 和/或我是否完全理解了一些错误?

1 个答案:

答案 0 :(得分:4)

在问题陈述的最后提出了两个具体问题;将它们列在下面。

Q值。 1)实际的默认行为是什么?

一个。如果未指定标识,并且客户端凭据类型为Windows,则默认为SPN,其值设置为服务端点地址的主机名部分,前缀为" host /"文字。如果服务在其中一个系统帐户下运行,或者在具有关联的SPN名称的域帐户下运行,并且计算机是Active Directory环境中的域成员,则此设置将利用Windows Kerberos安全性。

Q值。 2)为什么没有选择http / myhostname作为RFC4559的默认SPN?

一个。使用Web浏览器,您将以http / myhostname身份进行连接。但是对于WCF客户端,默认是按照上面的方式连接为host / myhostname。它肯定会在方案#2下连接到host / myhostname,你将身份设置为host / myhostname。

以上Q1和Q2的参考:Service Identity and Authentication

意见:由于各种原因,回归到NTLM。解决问题的方法是了解Kerberos失败的原因 - SPN问题是主要原因。诊断SPN问题的一个很好的参考是Blog of Brian Murphy-Booth - The biggest mistake: ServicePrincipalName’s

在浏览了Brian Murphy博客后,原始提问者随后发现,在问题场景中,正在使用端口。 "自动确定SPN时不使用端口。因此http://foo.example.com:1234导致host / foo.example.com作为SPN。当SPN不存在时,它会回退到NTLM,当SPN确实存在但不适合正确的用户时,它会抛出目标主体名称是不正确的异常。"