fragen stichworte

Howto WCF Service HTTPS-Bindung und Endpunktkonfiguration in IIS mit Load Balancer?

Wir haben einen WCF-Dienst, der auf einer Gruppe von 12 Maschinen gehostet wird. Es gibt einen Lastenausgleich, der ein Gateway zu diesen Maschinen ist.

Nun ist die Site als SSL eingerichtet. Ein Benutzer greift wie in einem Benutzer über eine URL mit https darauf zu. Ich weiß so viel, dass die URL, die die Site adressiert, https ist, aber keiner der Server hat eine https-Bindung oder ist so eingerichtet, dass er SSL benötigt. Dies lässt mich glauben, dass der Lastverteiler die HTTPS handhabt und die Verbindung vom Balancer zu den Servern unverschlüsselt ist (dies erfolgt hinter der Firewall, also kein großes Problem).

Das Problem, das wir haben, ist, dass ein Silverlight-Client versucht, auf einen WCF-Service zuzugreifen, und es wird der Fehler "Not Found" angezeigt. Ich habe zusammen mit unseren Entwicklercomputern eine Testseite eingerichtet und sichergestellt, dass die Bindungen und Endpunkte in der web.config mit dem Client funktionieren. In der Produktionsumgebung scheint es der Fall zu sein, dass wir diesen Fehler erhalten.

Stimmt etwas nicht mit der folgenden web.config? Sollten wir festlegen, wie https anders gehandhabt wird?

Derzeit ist dies ein Problem, da ich jede programmatische Lösung mit Endpunkten und Bindungen ausprobiert habe. Keine der Lösungen, die ich gefunden habe, betrifft einen Lastverteiler in unserer Art und Weise.

Informationen zum Web.config-Servicemodell:

 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="TradePMR.OMS.Framework.Services.CRM.CRMServiceBehavior">
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
        <behavior name="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregationBehavior">
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>          
      <customBinding>    
        <binding name="SecureCRMCustomBinding">
          <binaryMessageEncoding/>
          <httpsTransport/>
        </binding>

        <binding name="SecureAACustomBinding">
          <binaryMessageEncoding/>
          <httpsTransport/>
        </binding>
      </customBinding>
      <mexHttpsBinding>
        <binding name="SecureMex"/>
      </mexHttpsBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

    <!--Defines the services to be used in the application-->
    <services>
      <service behaviorConfiguration="TradePMR.OMS.Framework.Services.CRM.CRMServiceBehavior"
        name="TradePMR.OMS.Framework.Services.CRM.CRMService">

        <endpoint address="" binding="customBinding" bindingConfiguration="SecureCRMCustomBinding"
          contract="TradePMR.OMS.Framework.Services.CRM.CRMService" name="SecureCRMEndpoint"/>

        <!--This is required in order to be able to use the "Update Service Reference" in the Silverlight application-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>

      <service behaviorConfiguration="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregationBehavior"
        name="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregation">

        <endpoint address="" binding="customBinding" bindingConfiguration="SecureAACustomBinding"
          contract="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregation" name="SecureAAEndpoint"/>

        <!--This is required in order to be able to use the "Update Service Reference" in the Silverlight application-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Die ServiceReferences.ClientConfig sieht folgendermaßen aus:

<configuration>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="StandardAAEndpoint">
                    <binaryMessageEncoding/>
                    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
                </binding>
                <binding name="SecureAAEndpoint">
                    <binaryMessageEncoding/>
                    <httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
                </binding>
                <binding name="StandardCRMEndpoint">
                    <binaryMessageEncoding/>
                    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
                </binding>
                <binding name="SecureCRMEndpoint">
                    <binaryMessageEncoding/>
                    <httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="https://Service2.svc"
                binding="customBinding" bindingConfiguration="SecureAAEndpoint"
                contract="AccountAggregationService.AccountAggregation" name="SecureAAEndpoint"/>
            <endpoint address="https://Service1.svc"
                binding="customBinding" bindingConfiguration="SecureCRMEndpoint"
                contract="CRMService.CRMService" name="SecureCRMEndpoint"/>
        </client>
    </system.serviceModel>
</configuration>

(Die Adressen sind nicht von Belang, da diese dynamisch erstellt werden, sodass sie auf den Computer eines Entwicklers oder auf den Produktionsserver zeigen.)

antworten

Ich beantworte das, da ich von einigen Leuten gefragt wurde, die wissen, dass die App in Produktion ist, aber hier keine Antwort gefunden hat.

Im obigen Szenario konnten wir das nicht lösen. HTTPS vom Client zum Load Balancer ist in Ordnung. Das Problem ist, wenn der Lastausgleicher diese Verbindung annimmt und sie in einem unverschlüsselten Format an einen Webserver weiterleitet. Dies bricht scheinbar das WCF-Protokoll. Der Client sendet HTTPS-Kommunikationen, der Server erhält jedoch eine unverschlüsselte Kommunikation.

Wir haben das Problem gelöst, indem wir die gesamte SSL-Kommunikation durchgelassen haben.

Die beste "Lösung" besteht darin, festzustellen, ob Ihr WCF-Dienst nicht die HTTP-Übertragungsmethode verwendet und Ihren Load Balancer so konfiguriert hat, dass er diese Kommunikation unverändert durchläuft. Der Lastverteiler könnte dann seine normale Vorgehensweise für den von der Website generierten regulären HTTPS-Verkehr durchführen.

Ich habe dies nicht getestet, da unser Anwendungsszenario erfordert, dass der WCF-Dienst mit ASP.NET kompatibel ist.

Hoffentlich kann jemand anderes mit weiteren Informationen darauf eingehen.

Mir ist klar, dass das eine sehr alte Frage ist, aber ich bin kürzlich auf dieses Problem gestoßen und habe es mit den hier angegebenen Schritten gelöst:

https://blog.tonysneed.com/2012/06/18/building-scalable-and-secure-wcf-services/

Wie eine der anderen Antworten hier angibt, erfordert es die Unterklasse von HttpTransportElement und seinem BindingElementType, so dass es eine ISecurityCapabilities zurückgibt, die "WCF" zum Glauben verleitet, die Verbindung sei sicher. Sie können dieses Transportelement dann in einer benutzerdefinierten Bindung verwenden.

Wir sind auf das gleiche Problem gestoßen und haben eine Lösung von einem Entwickler von Microsoft erhalten. Diese Lösung besteht darin, einen benutzerdefinierten HttpTransport zu erstellen, der die Anforderung überschreibt, SSL vom Lastverteiler zum Server zu haben.