公共反向代理背后的 WCF Web 服务 [英] WCF Webservice behind public reverse proxy

查看:96
本文介绍了公共反向代理背后的 WCF Web 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I correctly serve WSDL of a WCF webservice located in a private LAN from behind a reverse proxy listening on public IP?

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

I have an Apache webserver configured in reverse proxy mode which listens for requests on a public IP address and serves them from the internal IIS host. WCF webservice generates WSDL using the FQDN address of the LAN host which, of course, cannot be read by an internet web service client.

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

Is there any setting that can be configured in wcf application's web.config or in IIS in order to customize the WSDL generated containing host address and put public address instead?

推荐答案

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

Add the following attribute to your service class:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>

这允许客户端将服务作为 https://... 寻址,但该服务仍然可以托管在 http://.....代码>

This allows the service to be addressed by the client as https://... but the service can still be hosted on http://.....

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

See my answer on How to specify AddressFilterMode.Any declaratively for how to create an extension to allow AddressFilterMode.Any to be specified through configuration without requiring code attributes.

在服务主机的 web.config 中,端点元素必须在地址属性中有一个绝对 URL,该地址属性是公共 URL客户.在同一端点元素中,将 listenUri 属性设置为服务主机正在侦听的绝对 URL.

In the web.config of the service host, the endpoint element must have an absolute URL in the address attribute that is the public URL that will be used by the client. In the same endpoint element, set the listenUri attribute to the absolute URL on which the service host is listening.

我确定主机正在侦听的默认绝对 URI 的方法是在客户端应用程序中添加一个服务引用,该引用指向托管服务的物理服务器.客户端的 web.config 将有一个服务地址.然后我将其复制到主机 web.config 中的 listenUri 属性中.

The way I determine what the default absolute URI the host is listening on is to add a service reference in a client application which points the the physical server where the service is hosted. The web.config of the client will have an address for the service. I then copy that into the listenUri attribute in the hosts web.config.

在您的服务行为配置中,添加具有属性 httpGetEnabled=true

In your service behavior configuration, add the element serviceMetaData with attribute httpGetEnabled=true

所以你会有这样的东西:

So you'll have something like this:

<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 >安全 >mode=none.由于传输是安全的(对于 ssl 负载平衡器),因此不存在安全问题.

I am not sure if this works with message security or transport security. For this particular application, the credentials were passed as part of the DataContract so we had basicHttpBinding > security > mode=none. Since the transport is secure (to the ssl load balancer) there were no security issues.

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

It is also possible in to leave the listenUri attribute blank, however it must be present.

不幸的是,WCF 中存在一个错误,即 WSDL 中导入模式的基地址具有 listenUri 基地址而不是公共基地址(使用端点的地址属性配置的基地址).要解决该问题,您需要创建一个 IWsdlExportExtension 实现,该实现将导入的模式直接引入 WSDL 文档并删除导入.

Unfortunately, there is a bug in WCF where the the base address of imported schemas in the WSDL have the listenUri base address rather than the public base address (the one configured using the address attribute of the endpoint). To work around that issue, you need to create an IWsdlExportExtension implementation which brings the imported schemas into the WSDL document directly and removes the imports.

使用 WCF 在 WSDL 中内联 XSD.此外,您可以让示例类继承自 BehaviorExtensionElement 并使用以下命令完成两个新方法:

An example of this is provided in this article on Inline XSD in WSDL with WCF. Additionally you can have the example class inherit from BehaviorExtensionElement and complete the two new methods with:

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 文件中添加扩展行为并使用配置添加行为,而不必创建服务工厂.

This will allow you to add an extension behavior in the .config file and add the behavior using configuration rather than having to create a service factory.

system.servicemodel 配置元素下添加:

Under the system.servicemodel configuration element add:

<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 属性在端点配置中引用新的端点行为

And then reference the new endpoint behavior in your endpoint configuration using the behaviorConfiguration attribute

<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior">

这篇关于公共反向代理背后的 WCF Web 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆