如何从监听公共(public) IP 的反向代理后面正确地提供位于专用 LAN 中的 WCF Web 服务的 WSDL?
我有一个配置为反向代理模式的 Apache Web 服务器,它监听公共(public) IP 地址上的请求并从内部 IIS 主机为这些请求提供服务。 WCF Web 服务使用 LAN 主机的 FQDN 地址生成 WSDL,当然,Internet Web 服务客户端无法读取该地址。
是否可以在 wcf 应用程序的 web.config 或 IIS 中配置任何设置,以便自定义生成的包含主机地址的 WSDL 并改为放置公共(public)地址?
最佳答案
将以下属性添加到您的服务类:
<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>
这允许客户端将服务寻址为 https://...
但该服务仍然可以托管在http://.....
上
请参阅我在 How to specify AddressFilterMode.Any declaratively 上的回答了解如何创建扩展以允许 AddressFilterMode.Any
通过配置指定,不需要代码属性。
在 web.config
对于服务主机,端点元素的地址属性中必须具有绝对 URL,该属性是客户端将使用的公共(public) URL。在同一端点元素中,设置 listenUri
属性为服务主机正在监听的绝对 URL。
我确定主机正在监听的默认绝对 URI 的方法是在客户端应用程序中添加一个服务引用,该引用指向托管服务的物理服务器。客户端的 web.config 将有一个服务地址。然后,我将其复制到主机 web.config 中的listenUri 属性中。
在您的服务行为配置中,添加元素 serviceMetaData
具有属性 httpGetEnabled=true
所以你会得到这样的东西:
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<!-- ... -->
<services>
<service name="NamespaceQualifiedServiceClass" behavior="myBehavior" >
<endpoint listenUri="http://www.servicehost.com"
address="https://www.sslloadbalancer.com"
binding="someBinding"
contract="IMyServiceInterface" ... />
</service>
</services>
我不确定这是否适用于消息安全或传输安全。对于这个特定的应用程序,凭据作为数据契约(Contract)的一部分传递,因此我们有 basicHttpBinding
> security
> mode=none
。由于传输是安全的(到 ssl 负载均衡器),因此不存在安全问题。
也可以将listenUri 属性留空,但它必须存在。
不幸的是,WCF 中存在一个错误,即 WSDL 中导入模式的基地址具有 ListenUri 基地址,而不是公共(public)基地址(使用端点的地址属性配置的基地址)。要解决该问题,您需要创建一个 IWsdlExportExtension 实现,它将导入的架构直接引入 WSDL 文档并删除导入。
Inline XSD in WSDL with WCF 上的这篇文章提供了一个示例。 。此外,您可以让示例类继承自 BehaviorExtensionElement
并完成这两个新方法:
Public Overrides ReadOnly Property BehaviorType() As System.Type
Get
Return GetType(InlineXsdInWsdlBehavior)
End Get
End Property
Protected Overrides Function CreateBehavior() As Object
Return New InlineXsdInWsdlBehavior()
End Function
这将允许您在 .config 文件中添加扩展行为,并使用配置添加该行为,而不必创建服务工厂。
根据system.servicemodel
配置元素添加:
<behaviors>
<endpointBehaviors>
<behavior name="SSLLoadBalancerBehavior">
<flattenXsdImports/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<!--The full assembly name must be specified in the type attribute as of WCF 3.5sp1-->
<add name="flattenXsdImports" type="Org.ServiceModel.Description.FlattenXsdImportsEndpointBehavior, Org.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
然后使用behaviorConfiguration属性在端点配置中引用新的端点行为
<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior">
关于公共(public)反向代理背后的 WCF Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/274984/