如何通过负载均衡器将wsHttpBinding与Message安全性一起使用

zim*_*nen 5 wcf load-balancing wshttpbinding

我有一个使用Message安全性的负载均衡服务:

<wsHttpBinding>
  <binding>
    <security mode="Message">
      <message clientCredentialType="Windows" establishSecurityContext="false" />
    </security>
  </binding>
</wsHttpBinding>
Run Code Online (Sandbox Code Playgroud)

我对此服务的所有调用都会打开和关闭自己的通道,因此建立安全上下文没有任何好处.

我正在使用WSHttpBinding与服务配置匹配的服务来调用服务:

ws.Security.Mode = SecurityMode.Message;
ws.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
ws.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
ws.Security.Message.EstablishSecurityContext = false;
Run Code Online (Sandbox Code Playgroud)

这有时会起作用,但有时我会遇到诸如此类的错误

安全上下文令牌已过期或无效.邮件未处理.

要么

安全令牌请求包含无效或格式错误的元素.

我终于发现将EstablishSecurityContext设置为false实际上并不会阻止使用安全上下文令牌.我们的负载均衡器目前不使用粘性会话,我试图避免走这条路.

我确实发现我应该能够在客户端上将NegotiateServiceCredential设置为false,以允许没有粘性会话的负载均衡器.我的服务已在AD帐户下运行,我可以在WSDL中看到它:

<Upn>User@Domain</Upn>
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将服务标识添加到我的客户端时

EndpointIDentity.CreateUpnIdentity("User@Domain")
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

不支持对在需要Kerberos多重标记的用户帐户下运行的服务进行身份验证.

如何通过负载均衡器调用我的服务?

Dan*_*ing 1

根据NegotiateServiceCredential的文档,您必须使用 SPN 身份而不是 UPN 运行服务:

如果此属性设置为 false,并且绑定配置为使用 Windows 作为客户端凭据类型,则服务帐户必须与服务主体名称 (SPN) 关联。为此,请在 NETWORK SERVICE 帐户或 LOCAL SYSTEM 帐户下运行该服务。或者,使用 SetSpn.exe 工具为服务帐户创建 SPN。无论哪种情况,客户端都必须在 <servicePrincipalName> 元素中使用正确的 SPN,或者使用 EndpointAddress 构造函数。

配置运行服务的 SPN 后,您的 WSDL 应显示 SPN 而不是 UPN,然后您必须修改客户端,以便:EndpointIdentity.CreateSpnIdentity("service_spn_name")

更新:

以下命令应正确配置 SPN:

setspn -A YourSvc/host.server.com domain\AppPoolAcccountName

  • YourSvc = 标识您的 svc 的名称
  • host.server.com = 托管您的服务的服务器的完全限定主机名

请参阅setspn的文档