公共(public)反向代理背后的 WCF Web 服务

标签 wcf wsdl reverse-proxy

如何从监听公共(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/

相关文章:

c# - 我可以将 WCF Web 服务限制为仅来自特定域的调用吗?

java - wsdl2java 在没有服务的情况下使用 Apache Axis2 for WSDL

windows - Apache 代理 - HTTP 到 HTTPS

c# - 将计算属性添加到 wcf 客户端以进行绑定(bind)

c# - Unity找不到部分类的构造函数

web-services - cxf-codegen-plugin 不生成代码

java - 解析 xmldsig-core/xmldsig-core-schema.xsd 时出错

nginx - 如何在 Docker 镜像中使用 Nginx 连接到我的应用程序?

linux - Apache ProxyPass 未加载资源

c# - 在 WCF MessageEncoder 中获取 HTTP header