负载平衡器后面WCF服务的WSDL生成

负载平衡器后面WCF服务的WSDL生成,wcf,ssl,load-balancing,svcutil.exe,Wcf,Ssl,Load Balancing,Svcutil.exe,背景: 我在IIS 7.0上有一个服务,它位于负载平衡器后面,当流量通过SSL时,它会解密SSL 服务所需的安全模式为混合模式,即TransportWithMessageSecurity 为了使服务能够接受HTTP流量,同时允许客户端通过SSL与负载平衡器通信,我创建了一个用户定义的绑定,它将自定义HttpTransportBindingElement添加到其通道堆栈中 自定义HttpTransportBindingElement反过来向框架声明它能够对消息进行加密和签名…因此,当流量通过HTT

背景:

我在IIS 7.0上有一个服务,它位于负载平衡器后面,当流量通过SSL时,它会解密SSL

服务所需的安全模式为混合模式,即TransportWithMessageSecurity

为了使服务能够接受HTTP流量,同时允许客户端通过SSL与负载平衡器通信,我创建了一个用户定义的绑定,它将自定义HttpTransportBindingElement添加到其通道堆栈中

自定义HttpTransportBindingElement反过来向框架声明它能够对消息进行加密和签名…因此,当流量通过HTTP通过它进入时,框架不会抱怨,因为传输声称它正在对消息进行签名/加密…即使它不是

(对于所有相关人员来说,这在安全方面是可以接受的,因为消息本来应该通过SSL到达负载平衡器…)

问题是:

当我们使用svcutil.exe生成客户端代理时,生成的自动生成的app.config文件包含通过HTTP寻址的服务端点这应该通过HTTPS进行

此外,当节点中的元素需要是元素时,它被定义为元素

我怀疑这是因为由服务器上的框架生成的WSDL是使用HTTP地址而不是HTTPS>构建的,这是使用自定义HttpTransportBindingElement的结果(如上所述)

客户端自动生成的app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
    <bindings>
        <customBinding>
            <binding name="myBindingEndpoint">
                <!--    WsdlImporter encountered unrecognized policy assertions in ServiceDescription 'http://tempuri.org/':    -->
                <!--    <wsdl:binding name='myBindingEndpoint'>    -->
                <!--        <sp:HttpToken xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">..</sp:HttpToken>    -->
                <security defaultAlgorithmSuite="Default" authenticationMode="CertificateOverTransport"
                    requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
                    keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
                    <localClientSettings cacheCookies="true" detectReplays="false"
                        replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
                        replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
                        sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
                        timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
                    <localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
                        maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
                        negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
                        sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
                        reconnectTransportOnFailure="true" maxPendingSessions="128"
                        maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
                    <secureConversationBootstrap />
                </security>
                <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
                    messageVersion="Default" writeEncoding="utf-8">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                </textMessageEncoding>
                <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                    maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
                    bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                    keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
                    realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                    useDefaultWebProxy="true" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="http://myserver/GAEASSLWcfService/ServiceOverSSL.svc"
            binding="customBinding" bindingConfiguration="myBindingEndpoint"
            contract="IServiceOverSSL" name="myBindingEndpoint" />
    </client>
</system.serviceModel>
</configuration>

解决办法:

只需将更改为并重新寻址端点以使用HTTPS即可解决此问题

但我们不希望必须指示我们的服务消费者更改他们的.config文件…我们的服务的使用应该尽可能地不可见

问题是:

如何确保客户端代理自动生成正确的地址和传输元素

参考资料: 对于那些想了解“负载平衡器/ssl解密程序背后的服务”和定制HttpTransportBindingElement解决方案的人,请参阅ZZZ的这篇关于构建用户定义绑定的文章XXX,以及ZZZ的这篇关于在负载平衡/SSL加速器后面公开服务的一些其他问题的文章XXX。

请检查。尝试配置:

<serviceBehaviors>
   <behavior name="<name>">
     <!-- Other options would go here -->
     <useRequestHeadersForMetadataAddress>
       <defaultPorts> <!-- Use your own port numbers -->
          <add scheme="http" port="81" />
          <add scheme="https" port="444" />
        </defaultPorts>
      </useRequestHeadersForMetadataAddress>
   </behavior>
</serviceBehaviors>

我也遇到了同样的问题,我的WSDL是用http方案生成的,而不是负载平衡器后面的https

我已经反映了WCF代码,并且找到了一个对我来说有效的解决方案

除了userequestheadersformetadataddress之外,还需要在serviceMetadata中关闭httpGetEnabled并打开httpsGetEnabled


另外,如果您像我想的那样使用.net 4,那么不要添加自定义的HttpTransportBindingElement,只需使用标准的HttpTransportBindingElement并在TransportSecurityBindingElement上设置AllowInsecureTransport。

您使用的是哪个wcf版本?我相信在.net 4中,这个问题已经解决了该项目的目标框架是.net 4.0-因此,这个问题似乎没有得到解决。您是否曾设法找到解决wsdl问题的方法。我们也遇到了同样的问题,我已经读过了,但是我觉得它不适用,因为我使用的是.NET4,这个修复程序是针对以前的版本的。不过,我还是试过了,似乎没什么区别。即使通过HTTPS浏览WSDL,仍然会导致HTTP寻址……如果我转到HTTPS//mydomain/GAEASSLWcfService/ServiceOverSSL.svc?WSDL代码,我会得到如下引用:HTTP//mydomain/GAEASSLWcfService/ServiceOverSSL.svc?xsd=xsd0Hi Sebastien,感谢您的贡献。我已经离开这个项目很久了,所以我无法检查你的答案是否解决了我的问题。但我会感谢你的努力…没问题,谢谢你。此外,为了能够使用负载平衡器后面的服务,除了地址之外,还需要在端点上配置侦听uri。客户端,您需要在具有给定侦听uri的端点上使用ClientViaBehavior。这将修复AddressFilter不匹配错误。我遇到了与@JTech完全相同的问题,上面的答案纠正了这个问题。唯一的问题是,在进行此修改之后,WSDL链接不再工作。我仍然可以通过…service.cs/mex在Visual Studio中添加对我的服务的引用,但我希望WSDL能够解析。