【问题标题】:Problem with WCF + NTLM authentication and load balancingWCF + NTLM 身份验证和负载平衡问题
【发布时间】:2011-09-20 17:15:03
【问题描述】:

再次尝试让我的 WCF 服务在我们的负载平衡环境中工作,我一直充满希望。我已经开始使用<customBinding>,因为recommendation 似乎是设置keepAliveEnabled 指令。

也就是说,我在服务器端设置 Windows 身份验证时遇到问题,因为 <customBinding> 似乎没有以相同的方式运行。

服务器端是这样的:

<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<bindings>
  <customBinding>
    <binding name="HttpBinding" closeTimeout="00:00:45">
      <textMessageEncoding>
        <readerQuotas maxStringContentLength="200000" maxArrayLength="200000" />
      </textMessageEncoding>
      <httpTransport keepAliveEnabled="false" maxReceivedMessageSize="200000" authenticationScheme="Negotiate"/>
    </binding>
  </customBinding>
</bindings>
<services>
    <endpoint address="http://svcserv/Services/ReportService/Reports.svc" binding="customBinding"
              bindingConfiguration="HttpBinding" contract="ReportService.IReports" >
    </endpoint>
    <endpoint address="mex" binding="customBinding" bindingConfiguration="HttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="ReportService.ReportsBehavior">
      <serviceMetadata httpGetEnabled="true"  />
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>

客户端如下所示:

<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<bindings>
  <basicHttpBinding>
    <binding name="CustomBinding_IReports" maxReceivedMessageSize="200000">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint name="CustomBinding_IReports" address="http://omsnetdev/Services/ReportService/Reports.svc"
            binding="basicHttpBinding" bindingConfiguration="CustomBinding_IReports" contract="ReportService.IReports">
    <identity>
      <servicePrincipalName value="host/svcserv"/>
      <dns value="svcserv"/>
    </identity>
  </endpoint>
</client>
</system.serviceModel>

如果我将 authenticationScheme 设置为“协商”,那么我会收到类似于SOAP header Action was not understood. 或在某一时刻Client found response content type of '', but expected 'application/soap+xml'. 的内容 如果我将 authenticationScheme 更改为“Ntlm”,那么我会收到Exception: The request failed with HTTP status 401: Unauthorized.,但我认为这是由于协商失败(due to the SPN value?),所以它会退回到“Ntlm”并失败。

我会将此作为 IIS 服务器上的配置注销,但我已经验证了这些设置。

【问题讨论】:

  • 我修改了标题以使这个问题更具描述性。

标签: .net wcf wcf-security


【解决方案1】:

我相信这不仅仅是 WCF 问题,而是一个概念模型。您希望制作完全无状态的场景,但同时您需要对身份验证进行有状态处理,因为 NTLM(并且没有其他传输级别身份验证)是在单个请求响应中执行的。

这里是握手如何工作的简短描述:

      Client                                                Server
-----------------------------------------------------------------------------------------
Send initial request ---------------------------->
                     <----------------------------  Returns 401 with WWW-Authenticate 
                                                    header demanding NTLM
Sends empty request  ---------------------------->  
with Authorization                                
header with initial 
token                                    
                     <----------------------------  Returns 401 with WWW-Authenticate 
                                                    header containing some server token
Sends request with   ---------------------------->  
Authorization header                                
with final token                                    
                     <----------------------------  Returns 200 and expected response

此握手必须在单个负载平衡服务器上执行,但一旦您关闭持久 HTTP 连接,您将强制您的客户端为每个调用打开新的 TCP 连接,并且每个调用都单独进行负载平衡。这很可能以传递给不同服务器的这些调用结束=>身份验证失败。简而言之,您需要:

  • 在 HTTP 之上运行的更高级别的负载平衡(身份验证将使用负载平衡器完成)并且对服务的调用将是匿名的
  • 在消息中传递凭据的另一种身份验证技术
  • 持久连接强制请求路由到正确的服务器。如果您在 IIS 中托管服务,则可以将保持活动间隔减少到几秒钟,并希望这将提高负载平衡效率

【讨论】:

  • 握手描述做得很好。感谢您为提高我的理解而努力工作。我经常发现许多答案都很好,但并不能真正帮助解释根本问题。
  • 你能解释一下持久连接和keep-alive间隔的概念吗?似乎通过将 keep-alive 设置为几秒钟,这将与持久性相反?
  • 持久并不意味着永久。持久连接用于后续调用,如果未使用,则在保持活动间隔后终止(类似于不活动超时)。因此,您可以设置较短的保持活动间隔以将相关调用保持在一起,但使负载平衡更加频繁。但这也取决于客户来电的频率。
【解决方案2】:

如果您有与 SPN 相关的问题,请查看此答案:SO WCF-Security-Problem question

使用负载均衡器时您应该遇到的唯一问题是您是否需要将会话保持“粘性”到一台主机。对于给定的会话,如果您正确配置负载均衡器,它应该能够为您执行此操作。

请注意,如果服务器和客户端在同一台机器上,Windows 服务器有一个不使用 SSPI 的回退模式。这会让你在从测试转向生产时被烧毁。

【讨论】:

  • 这里提到了我要调查的“双跳”。它准确地提到了我的“401:未经授权”问题,所以我充满希望!谢谢!
  • 我正在尝试确定这是否是我的 SPN 设置不正确或网络服务器的配置问题。有什么方法可以确定吗?
猜你喜欢
  • 2021-06-06
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 1970-01-01
  • 2020-08-31
  • 2018-01-24
相关资源
最近更新 更多