2

由于这个问题,指定no 时的默认行为identityhost/myhostname.

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

我有一个 SOAP WCF 服务(它是一个 Dynamics NAV Web 服务,但这对于以下内容应该无关紧要,因为问题完全是关于客户端的角度),如果我不指定任何身份,它就不起作用。

服务器实际上是在域用户帐户下运行的。 host/myhostname指定但不针对此用户帐户,仅针对机器帐户。 http/myhostname为此域用户帐户指定。

让我们看三个场景:

未指定身份

EndpointAddress使用以下代码创建:

new EndpointAddress(new Uri(endpoint))

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

  • 没有标头的 HTTP POST Authorization
  • 用 响应WWW-Authenticate: Negotiate
  • 带有标头的 HTTP POST Authorization: Negotiate XXXXXX是 1584 个 BASE64 编码字节,以96 130 6. 我在里面找不到任何可读的 ASCII。
  • Authorization: Negotiate XXX带有标题的响应。XXX是 126 个 BASE64 编码字节。我在里面找不到任何可读的 ASCII。
  • 带有标头的 HTTP POST Authorization: Negotiate XXXXXX是 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。所以肯定是有区别的

这是正在发生的事情:

  • 没有标头的 HTTP POST Authorization
  • 用 响应WWW-Authenticate: Negotiate
  • HTTP POST,Authorization: Negotiate XXX其中 XXX 是 40 个 BASE64 编码字节。第一个字节是 ASCII 字母NTLMSSP
  • 响应WWW-Authenticate: Negotiate XXX其中 XXX 是 270 个 BASE64 编码字节。第一个字节是 ASCII 字母NTLMSSP。FQDN 似乎也被编码为 ASCII。
  • 带有 的 HTTP POST 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并且由于RFC 4559http/myhostname似乎是正确的选择时,它可以工作。这是配置:

var identity = EndpointIdentity.CreateSpnIdentity(@"http/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);

这就是正在发生的事情:

  • 没有标头的 HTTP POST Authorization
  • 用 响应WWW-Authenticate: Negotiate
  • 带有标头的 HTTP POST Authorization: Negotiate XXX。XXX 是 1580 BASE64 编码字节。没有 ASCI 迹象。
  • 以有效载荷响应。

这个问题不是关于让它工作的热度,而是关于理解。令我困惑的是第一个示例和第二个示例之间的区别。我的想法是:

  1. 如果默认身份是host/myhostname,
  2. 手动指定身份应该没有区别host/myhostname
  3. 但有区别
  4. 所以这不能是默认身份。

所以我的问题是

  1. 实际的默认行为是什么,以及
  2. 为什么http/myhostname由于 RFC4559 而没有被选为默认 SPN?

和/或我是否理解完全错误的事情?

4

1 回答 1

4

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

问:1) 实际的默认行为是什么?

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

Q. 2) 为什么 http/myhostname 由于 RFC4559 而没有被选为默认 SPN?

A. 使用 Web 浏览器,您将连接为 http/myhostname。但是对于 WCF 客户端,默认情况下是按照上面的主机/myhostname 连接。在您将身份设置为 host/myhostname 的场景 #2 下,它肯定会连接到 host/myhostname。

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

评论:由于多种原因,会退回到 NTLM。解决这个问题的方法是了解 Kerberos 失败的原因——SPN 问题是主要原因。诊断 SPN 问题的一个很好的参考是Brian Murphy-Booth 的博客 - 最大的错误:ServicePrincipalName 的

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

于 2016-12-08T12:44:04.067 回答