简体   繁体   English

在负载均衡器和SSL后面配置WCF

[英]Configuring WCF behind a load balancer and SSL

Variations of this question have been asked all over SO, and through those questions I have been able to get my configuration 90% of the way, but I am still having some problems. 这个问题的变化已经被问到了所有问题,通过这些问题,我能够在90%的时间内完成配置,但是我仍然遇到了一些问题。 My setup looks like this: 我的设置如下:

                                (http://server1)
                                 ----------------
                            -->  -- webserver1 --
                           /     ----------------
                          /
 (https://externaldomain)/
 ---------------------- /
 --- load balancer ---- 
 ---------------------- \
                         \
                          \
                           \     (http://server2)
                            -->  ----------------
                                 -- webserver2 --
                                 ----------------

I have specified 我指定了

 <useRequestHeadersForMetadataAddress>
    <defaultPorts>
      <add scheme="https" port="443" />
    </defaultPorts>
  </useRequestHeadersForMetadataAddress>

and I have set httpGetEnabled to false and httpsGetEnabled to true. 我已将httpGetEnabled设置为false,将httpsGetEnabled为true。 The result is that when I navigate to https://externaldomain I see the default service screen and it displays the correct URLs eg svcutil https://externaldomain/svc.cs?wsdl 结果是,当我导航到https://externaldomain我看到默认服务屏幕并显示正确的URL,例如svcutil https://externaldomain/svc.cs?wsdl

I have two problems: 我有两个问题:

  1. If I try to navigate to https://externaldomain/svc.cs?wsdl the WSDL is not shown, instead I get redirected back to the default service screen. 如果我尝试导航到https://externaldomain/svc.cs?wsdl ,则不显示WSDL,而是将我重定向回默认服务屏幕。 I am still able to add a reference to this service in Visual Studio via: https://externaldomain/svc.cs/mex , but I would like the WSDL to be available as well. 我仍然可以通过以下方式在Visual Studio中添加对此服务的引用: https://externaldomain/svc.cs/mex ,但我希望WSDL也可用。
  2. When I add the service reference to Visual Studio, the binding that gets added to the config is setup as an httpTransport and the endpoint points at http and not https. 当我将服务引用添加到Visual Studio时,添加到配置的绑定被设置为httpTransport,端点指向http而不是https。 If I manually change this to an https transport and change the URL to https for the endpoint everything works fine. 如果我手动将其更改为https传输并将URL更改为端点的https,则一切正常。 This isn't ideal. 这不太理想。

Can someone point me in the direction of some documentation on what I need to change to resolve these two problems? 有人能否指出我需要改变哪些文档来解决这两个问题? The config for my Service is below. 我的服务配置如下。

<system.serviceModel>
    <client>
      <endpoint address="http://internalService" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMessageProcessing" contract="IMessageProcessing" name="BasicHttpBinding_IMessageProcessing" />
    </client>
    <services>
      <service behaviorConfiguration="ProcessBehavior" name="Service">
        <host>
          <baseAddresses>
            <add baseAddress="https://externaldomain/Service.svc" />
          </baseAddresses>
        </host>
        <endpoint binding="customBinding" bindingConfiguration="CompressionBinding" name="CompressionBindingEndpoint" contract="IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ProcessBehavior">
          <serviceThrottling maxConcurrentCalls="100" />
          <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<useRequestHeadersForMetadataAddress>
        <defaultPorts>
          <add scheme="https" port="443" />
        </defaultPorts>
      </useRequestHeadersForMetadataAddress>
          <serviceDebug includeExceptionDetailInFaults="true" />
          <!--<serviceThrottling maxConcurrentCalls="200"/>-->
        </behavior>
        <behavior name="metadataSupport">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IMessageProcessing" />
      </basicHttpBinding>
      <customBinding>
        <binding name="CompressionBinding" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:15:00" sendTimeout="01:30:00">
          <binaryMessageEncoding compressionFormat="GZip" />
          <httpTransport maxReceivedMessageSize="2147483600" decompressionEnabled="true" />
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>

---------EDIT----------- - - - - -编辑 - - - - - -

The issue with the endpoint downloading with an HTTP transport was kind of a 'duh' on my part. 使用HTTP传输进行端点下载的问题对我来说是一种“呃”。 In the binding for the endpoint I specify: 在端点的绑定中,我指定:

<httpTransport maxReceivedMessageSize="2147483600" decompressionEnabled="true" />

Changing this to httpsTransport adds the service reference with an https transport, but the client application is then unable to reach the endpoint. 将此更改为httpsTransport会使用https传输添加服务引用,但客户端应用程序无法访问端点。 Since the load balancer is communicating via http the transport has to remain http. 由于负载均衡器通过http进行通信,因此传输必须保持为http。 I could specific a second endpoint with an https binding but that is messy. 我可以使用https绑定来指定第二个端点,但这很麻烦。

I still haven't figured out the wsdl issue though. 我仍然没有想出wsdl问题。

I have done something similar in the past. 我过去做过类似的事。 I had a sql based routing table to pick "route to"(R2) server (webserver1, webserver2). 我有一个基于sql的路由表来选择“路由到”(R2)服务器(webserver1,webserver2)。 So my load balancer picks up the message and then selects a R2 server based on some values in the message and passes it (calls a web service on R2) on to R2 server. 因此,我的负载均衡器接收消息,然后根据消息中的某些值选择R2服务器,并将其传递给R2服务器(在R2上调用Web服务)。

SOAP maintains security information in the message header. SOAP在消息头中维护安全信息。 ( https://msdn.microsoft.com/en-us/library/ms951257.aspx ). https://msdn.microsoft.com/en-us/library/ms951257.aspx )。 So what I did was once the message arrives at the load balancer, I created a new instance of the message and assigned all properties from the incoming message to new message. 所以我做的是一旦消息到达负载均衡器,我创建了一个新的消息实例,并将传入消息中的所有属性分配给新消息。 That means the new message will not have the same headers as incoming message. 这意味着新邮件将不会与传入邮件具有相同的标头。 Which means we should be able to send the new message to http. 这意味着我们应该能够将新消息发送到http。

R2 server processes the message and sends an acknowledgement back to load balancer. R2服务器处理该消息并将确认发送回负载均衡器。 Finally load balancer passes on the acknowledgement to the client. 最后,负载均衡器将确认传递给客户端。 The most important point to note is load balancer and R2 server should have the same wsdl. 最重要的一点是负载均衡器和R2服务器应该具有相同的wsdl。 Let us know how you go with this. 让我们知道你如何使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM