c# - 使用 wsHttpBinding 和 Message Security 使用客户端凭据类型窗口对 WCF 进行负载平衡

标签 c# wcf load-balancing wcf-security ws-security

我们有一个正常的 WCF 服务,它具有如下所示的绑定(bind):

 <wsHttpBinding>
 <binding name="ServiceBinding" receiveTimeout="00:10:00" sendTimeout="00:10:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxReceivedMessageSize="20971520"
                messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">                   
                <security mode="Message">
                      <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        establishSecurityContext="false" />
                </security>
            </binding>
</wsHttpBinding>

此服务位于负载均衡器后面的 2 个服务器中。正如此处建议的那样

http://msdn.microsoft.com/en-us/library/vstudio/hh273122(v=vs.100).aspx

我已将 establishSecurityContext 设置为 false。当我运行调用该服务时,我遇到与无效安全上下文 token 相关的间歇性问题。尽管我说不要建立 SeurityContext,但似乎 WCF 正在执行所有正常的握手操作。

此时,由于要求,使用 Cert、BasicHttBinding 或无安全性不是一种选择。

我什至让基础架构团队在负载均衡器中启用粘性 session ,但似乎没有任何效果像我们预期的那样工作。

我和我的团队几乎完成了互联网上所说的所有事情,但是当有负载均衡器时似乎没有任何效果,而当没有负载均衡器时此绑定(bind)工作完美。

有人幸运地使用了这个绑定(bind)吗?

我们正在争取 Microsoft dispatch WCF 专家,但显然很难找到人。

我怎样才能让这个东西与负载平衡器很好地协同工作?

最佳答案

您设置了 negotiateServiceCredential="true"。这意味着安全上下文是在初始交换期间创建的,但此上下文不会在后续调用中使用(因为 establishSecurityContext="false")。协商过程允许客户端安全地获取服务器凭据。然后客户端使用这些凭据来保护消息。这就是为什么所有“握手的事情”都会发生。

本文描述了这种情况:"Message Security with a Windows Client" .

当您使用负载均衡器时需要安全协商(因为实际服务器的凭据取决于将服务请求的机器),除非您对平衡器后面的所有服务实例使用相同的凭据。在后一种情况下,您可以设置 negotiateServiceCredential="false"并在配置或代码中指定服务器凭据。例如,您可以使用 clientCredentialType="Certificate"并为所有计算机使用相同的服务器证书。或者你可以 clientCredentialType="Windows"并为域用户配置任意 SPN,用于运行平衡器后面的所有服务(我没有尝试这种情况,请参阅下面的详细信息)。

在您的情况下,negotiateServiceCredential="true"。所以可能的问题是:

1) 粘性 session 可能无法正常工作。您可以通过使用返回的 BasicHttBinding 实现简单的 WCF 服务来测试它

String.Format("{0}{1}", prefix, DateTime.Now);

在平衡器后面的一台服务器上的应用程序设置中配置 prefix=""和 prefix="!!!!!!!!!!!!!”另外一个。然后多次循环调用此服务并记录结果。您会看到粘性 session 是否存在问题。

2) 如果粘性 session 正常工作,请确保您的配置在未使用平衡时适用于所有服务器。

当你不能使用粘性 session 时,你应该设置negotiateServiceCredential="false"。不使用协商,因此客户端应该在代码或配置中显式配置服务器凭据。要在不协商的情况下使用 Windows 凭据类型,服务的用户帐户必须有权访问在 Active Directory 域中注册的服务主体名称 (SPN)。请参阅 "Message Security with a Windows Client without Credential Negotiation" 中的详细信息和示例

要使用任意 SPN,您应该将您的服务配置为在同一 Windows 域帐户下运行。要为帐户设置任意 SPN,您可以在域 Controller 上使用 setspn 实用程序:

setspn a AcmeService/GlobalBank WS_Account

Kerberos Technical Supplement for Windows 中所述

另请参阅关于 Message Security 的文章用于描述各种场景和相应的设置。

关于c# - 使用 wsHttpBinding 和 Message Security 使用客户端凭据类型窗口对 WCF 进行负载平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25055078/

相关文章:

node.js - 具有多个 Node 的多人游戏服务器

c# - c#中SQL时间戳的等效类型是什么

c# - DataContract 和继承?

C# COM => 指针 => delphi 接口(interface)

c# - 人脸识别检测情绪

WCF 接口(interface)作为参数

c# - .NET和负载均衡器?

apache - 可以在没有粘性 session 的情况下进行 session 复制吗?

c# - 将值从 java 脚本传递到隐藏字段不起作用

c# - WMI 查询的 select 子句中的数学运算