寻找WCF解决方案在自定义绑定的负载均衡环境中传递用户凭据

时间:2010-08-24 14:48:09

标签: wcf wcf-binding wcf-security

我们目前支持在负载平衡环境中运行的多个WCF服务。过去,我们使用 wsHttpBinding 并将 establishSecurityContext 设置为 false ,以使服务能够与我们的负载均衡器一起正常运行。

我们遇到的一个问题是 wsHttpBinding 默认加密返回结果,显然无法关闭。这会导致我们网络上的Riverbed压缩设备出现问题 - 即加密数据压缩得不好(或者根本没有)。

现在我们正在尝试使用 basicHttpBinding ,因为默认情况下它不会加密数据。我们有两个要求:

  1. 使用负载均衡器 - 这可能是通过将 keepAliveEnabled 设置为false来实现的。这需要使用自定义绑定。例如:

    <customBinding>  
      <binding name="NewBinding0">  
        <httpTransport authenticationScheme="Ntlm" **keepAliveEnabled="false"** />  
      </binding>  
    </customBinding>  
    
  2. 传递用户凭据 - 这似乎可以通过将安全模式设置为 TransportCredentialOnly 来实现。这可以通过 basicHttpBinding 获得。例如:

    <basicHttpBinding>  
      <binding name="NewBinding1">  
        <security **mode="TransportCredentialOnly"** />  
      </binding>  
    </basicHttpBinding>  
    
  3. 现在我的实际问题是: - )...如何/可以将上述两个要求合并为一个自定义绑定?对于自定义绑定,上面的#2 相当于什么?如何让它传递用户凭据?

    谢谢!

1 个答案:

答案 0 :(得分:1)

事实证明,我能够使用以下绑定配置使用自定义绑定执行我想要的操作:

<customBinding>
 <binding name="NewBinding0">
 <httpTransport authenticationScheme="Ntlm" keepAliveEnabled="false" />
 </binding>
</customBinding>

然后,在客户端,我可以使用以下代码获取WCF服务在(在IIS中)运行的应用程序池的标识以及实际调用WCF服务的用户的标识: / p>

public string GetData(int value)
{
  var callingUser = string.Empty;
  var appPoolUser = WindowsIdentity.GetCurrent().Name;
  var identities =
    OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties["Identities"] as
    IList<IIdentity>;

  if (identities != null)
  {
    var result = from i in identities
            where i.AuthenticationType == "NTLM"
            select new { i.Name };

    if (result.Count() > 0)
    {
      callingUser = result.First().Name;
    }

  }

  return string.Format("Value Entered: {0}; AppPool User: {1}; Calling User: {2}", value,
          appPoolUser, callingUser);
}

我在负载平衡环境中测试了上面的代码,对于需求#1,一切似乎运行得很好。测试在负载平衡环境中模拟了100个用户负载10分钟。我们在测试期间关闭了其中一个负载平衡服务器,并且所有内容都按预期继续运行(即测试期间没有抛出任何异常,也没有错误地返回任何身份)。

上面的代码是需求#2的关键部分,我错过了 - 也就是说,直到这项研究,WCF才会给你多个身份。

此外,使用此配置,WCF调用的结果未加密(这是我们想要的)。所以,我认为这种配置对我们的情况很有用。