您设置negotiateServiceCredential=“true”。这意味着安全上下文是在初始交换期间创建的,但该上下文不会在后续调用中使用(因为 setSecurityContext="false")。协商过程允许客户端安全地获取服务器凭据。然后客户端使用这些凭据来保护消息。这就是所有“握手事件”发生的原因。
本文描述了这种情况:“Windows 客户端的消息安全性” http://msdn.microsoft.com/en-us/library/ms729709(v=vs.110).aspx.
当您使用负载均衡器时,需要进行安全协商(因为实际服务器的凭据取决于将服务请求的计算机),除非您对均衡器后面的所有服务实例使用相同的凭据。在后一种情况下,您可以设置 negotiateServiceCredential="false" 并在配置或代码中指定服务器凭据。例如,您可以使用 clientCredentialType="Certificate" 并为所有计算机使用相同的服务器证书。或者您可以 clientCredentialType="Windows" 并向域用户配置任意 SPN,该 SPN 用于运行平衡器后面的所有服务(我没有尝试这种情况,请参阅下面的详细信息)。
根据您的情况,协商服务凭证=“true”。所以可能的问题是:
1) 粘性会话可能无法正常工作。您可以通过使用返回的 BasicHttBinding 实现简单的 WCF 服务来测试它
String.Format("{0}{1}", prefix, DateTime.Now);
在平衡器后面的一台服务器上的应用程序设置中配置 prefix="" 和 prefix="!!!!!!!!!!!!"另外一个。然后循环调用该服务多次并记录结果。您将查看粘性会话是否存在问题。
2) 如果粘性会话正常工作,请确保您的配置在未使用平衡时适用于所有服务器。
当您无法使用粘性会话时,您应该设置negotiateServiceCredential=“false”。不使用协商,因此客户端应该在代码或配置中显式配置服务器凭据。要在不协商的情况下使用 Windows 凭据类型,服务的用户帐户必须有权访问在 Active Directory 域中注册的服务主体名称 (SPN)。请参阅详细信息和示例“无需凭据协商的 Windows 客户端的消息安全性” http://msdn.microsoft.com/en-us/library/ms735117(v=vs.110).aspx
要使用任意 SPN,您应该将服务配置为在同一 Windows 域帐户下运行。要为帐户设置任意 SPN,您可以在域控制器上使用 setspn 实用程序:
setspn a AcmeService/GlobalBank WS_Account
如中所述适用于 Windows 的 Kerberos 技术补充 http://msdn.microsoft.com/en-us/library/aa480609.aspx
另请参阅有关的文章消息安全 http://msdn.microsoft.com/en-us/library/ff647344.aspx用于描述各种场景和相应的设置。