8

有一个简单的 WCF 演示应用程序,它有两个控制台项目——主机和客户端。两者都在我的机器上运行(win 7 box)。我正在使用 netTcpBinding,它使用 Windows 身份验证。

问题是身份验证从 kerberos 降级到 NTLM,我不知道为什么。

如果我使用

<clientCredentials>
   <windows allowNtlm="true" />
</clientCredentials>

在客户端,一切都很酷。但是,如果我将其更改为false,则会出现以下异常:

SecurityNegotiationException:远程服务器不满足相互身份验证要求。

这表明 kerberos 失败,并且由于客户端不允许 NTLM,因此调用会导致引发异常。

这是项目的问题,还是我的开发机器配置造成的外部问题?


解决方案:

显然,我必须在客户端配置中指定服务器的身份。就我而言,服务器以我的身份运行,因此我修改了客户端:

<client>
  <endpoint address="net.tcp://dev7.HurrDurr.com:12345/MyService" 
            binding="netTcpBinding" 
            bindingConfiguration="MyBindingConfigurationLol" 
            behaviorConfiguration="HurrDurrServiceEndpoint" 
            contract="ShaolinCore.ICommunicationService">
    <!-- start changes here -->
    <identity>
      <userPrincipalName value="myusername@mydomain"/>
    </identity>
    <!-- end changes here -->
  </endpoint>
</client>

我不确定为什么这可以解决问题。好的,现在在客户端我完全信任服务器(嘿,我认识那个人!)。但是既然 NTLM 不如 kerberos 安全,为什么不反过来呢?如果我不完全信任服务器,我使用 kerberos,否则 ntlm 很好。

或者,OTOH,如果我不完全信任服务器,为什么它根本工作?“SecurityException:未设置端点身份。WCF 无法信任服务器的身份,不会传输客户端身份。”

4

4 回答 4

8

当我在 IIS4、5 和 6 开发团队工作时,我们经常遇到这种情况!要使 Curb 工作,您需要满足以下条件:

1)双方都支持遏制(今天所有支持的Windows版本都支持遏制)

2) 机器对 Active Directory 的身份验证

3) 为服务器端点注册的服务主体名称 (SPN)。在“过去的美好时光”中,您必须使用 SetSPN.exe 手动执行此操作。SPN 只是 Curb 将连接到的端点;它需要这些数据来支持相互授权。大多数应用程序会为您调用 appprop API 来完成这项工作 (DsWriteAccountSpn)

如果上述任何步骤不正确,Windows通常默认使用 NTLM,它只为您提供客户端身份验证。

希望有帮助!- 迈克尔

于 2010-02-23T22:16:27.643 回答
2

通过 MSDN 仅供参考:netTcpBinding:默认绑定使用带有协商身份验证的传输安全性。此协商尝试使用 Kerberos,但如果这不起作用,它将回退并使用较旧的 NTLM 协议。如果您在域环境中,Kerberos 是一个不错的选择;为了使用它,您需要您的服务和客户端都在域帐户下运行。您还需要为您的服务配置服务主体名称 (SPN)。

于 2010-02-23T18:52:48.360 回答
1

服务器是如何配置的?配置文件中有<authentication mode="Windows"/>and吗?<identity impersonate="true"/>

您可以通过配置文件中的身份验证标签设置身份验证模式:

<configuration>
  <system.web>
    <authentication mode="Windows" />
  </system.web>
</configuration>
于 2010-02-23T14:58:07.980 回答
1

也许 MSDN 上的这个页面 -调试 Windows 身份验证错误- 帮助您弄清楚发生了什么 - 关于何时使用 NTLM 与 Kerberos 似乎相当棘手。

于 2010-02-23T15:18:59.150 回答