9

如何从侦听公共 IP 的反向代理后面正确地提供位于专用 LAN 中的 WCF Web 服务的 WSDL?

我有一个配置为反向代理模式的 Apache 网络服务器,它侦听公共 IP 地址上的请求并从内部 IIS 主机为它们提供服务。WCF Web 服务使用 LAN 主机的 FQDN 地址生成 WSDL,当然,互联网 Web 服务客户端无法读取该地址。

是否可以在 wcf 应用程序的 web.config 或 IIS 中配置任何设置,以便自定义生成的包含主机地址的 WSDL 并改为放置公共地址?

4

3 回答 3

11

将以下属性添加到您的服务类:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>

这允许服务由客户端处理,https://...但服务仍然可以托管在http://.....

请参阅我关于如何以声明方式指定 AddressFilterMode.Any的回答,了解如何创建扩展以允许AddressFilterMode.Any 通过配置指定而不需要代码属性。

web.config服务主机中,端点元素的地址属性中必须有一个绝对 URL,即客户端将使用的公共 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>

我不确定这是否适用于消息安全或传输安全。对于这个特定的应用程序,凭据是作为 DataContract 的一部分传递的,所以我们有basicHttpBinding>> securitymode=none由于传输是安全的(对于 ssl 负载均衡器),因此不存在安全问题。

也可以将 listenUri 属性留空,但它必须存在。

不幸的是,WCF 中存在一个错误,其中 WSDL 中导入模式的基地址具有 listenUri 基地址而不是公共基地址(使用端点的地址属性配置的基地址)。要解决该问题,您需要创建一个 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">
于 2009-06-03T21:10:34.210 回答
1

我遇到了类似的问题,其中之一是公共地址和服务器地址的解析。这解决了这个问题,尽管我仍然有几个身份验证问题。

请参阅如何在 WSDL 中为 IIS 托管服务更改主机名?作者:董文龙

档案

于 2009-01-21T08:13:58.997 回答
0

请参阅:Aaron Skonnard 的服务站 WCF 深度寻址

存档链接

于 2008-12-30T08:28:59.087 回答