为什么 WCF 中 kerberos 默认为 NTLM?
得到了一个简单的 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 无法信任服务器的身份,并且不会传输客户端身份。”
Got a simple WCF demo app that has two console projects--host and client. Both are running on my machine (win 7 box). I'm using the netTcpBinding, which uses windows authentication.
The issue is that authentication is downgrading to NTLM from kerberos, and I can't figure out why.
If I use
<clientCredentials>
<windows allowNtlm="true" />
</clientCredentials>
on the client side, everything is cool. But if I change that to false
, I get the following exception:
SecurityNegotiationException: The
remote server did not satisfy the
mutual authentication requirement.
This suggests that kerberos is failing and since the client won't allow NTLM the call results in an exception being thrown.
Is this an issue with the project, or is it an external issue caused by the configuration of my development machine?
Solution:
Apparently, I have to specify the identity of the server within the client configuration. In my case, the server is running under my identity, so I modify the client thusly:
<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>
I'm not sure why this fixes the issue. Okay, now on the client side I fully trust the server (hey, I know that guy!). But since NTLM is less secure than kerberos, why isn't it the other way around? If I don't fully trust the server, I use kerberos, otherwise ntlm is fine.
Or, OTOH, if I don't fully trust the server why does it work at all? "SecurityException: Endpoint identity not set. WCF cannot trust the identity of the server and will not transmit client identity."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当我在 IIS4、5 和 6 开发团队工作时,我们经常遇到这种情况!要使 Curb 发挥作用,您需要满足以下条件:
1) 双方都支持遏制(目前所有受支持的 Windows 版本都支持 Curb)
2) 计算机对 Active Directory 进行身份验证
3) 为服务器端点注册的服务主体名称 (SPN) 。在“美好的过去”,您必须使用 SetSPN.exe 手动完成此操作。 SPN 只是 Curb 将连接到的端点;它需要这些数据来支持相互验证。大多数应用程序将调用 appprop API 来为您完成这项工作 (DsWriteAccountSpn)
如果上述任何步骤不正确,Windows 通常将默认为 NTLM,它只为您提供客户端身份验证。
希望有帮助!
- 迈克尔
When I worked on the IIS4, 5 and 6 development teams we ran into this a lot! For Kerb to work, you need the following conditions to be true:
1) Both parties support kerb (all supported versions of Windows support Kerb today)
2) Machines auth to Active Directory
3) Service Principal Names (SPNs) registered for the server endpoint. In the "good old days" you had to do this by hand using SetSPN.exe. An SPN is just an endpoint that Kerb will connect to; it needs this data to support mutual authn. Most apps will call the approp API to this work for you (DsWriteAccountSpn)
If any of the steps above are not true, Windows will usually default to NTLM, whcih gives you only client authentication.
Hope that helps!
- Michael
仅供参考,来自 MSDN:
netTcpBinding:默认绑定使用具有协商身份验证的传输安全性。 此协商尝试使用 Kerberos,但如果不起作用,它将回退并使用较旧的 NTLM 协议。如果您处于域环境中,Kerberos 是一个不错的选择;为了使用它,您需要您的服务和客户端都在域帐户下运行。您还需要为您的服务配置服务主体名称 (SPN)。
Fyi via MSDN:
netTcpBinding: The default binding uses transport security with negotiated authentication. This negotiation attempts to use Kerberos, but if that doesn't work, it'll fall back and use the older NTLM protocol. Kerberos is a great choice if you're in a domain environment; in order to use it, you'll need both your service and clients to be running under domain accounts. You'll also want to configure a service principal name (SPN) for your service.
也许 MSDN 上的这个页面 - 调试 Windows 身份验证错误 - 可以帮助您了解弄清楚发生了什么 - 何时使用 NTLM 与 Kerberos 似乎相当棘手。
Maybe this page on MSDN - Debugging Windows Authentication Errors - helps you figure out what's going on - seems to be quite tricky as to when NTLM vs. Kerberos is being used.
服务器是如何配置的?您的配置文件中是否有
和
?您可以通过配置文件中的身份验证标签设置身份验证模式:
How is the server configured? Do you have the
<authentication mode="Windows"/>
and<identity impersonate="true"/>
in the config file?You set the authentication mode via the authentication tag in the config file: