穿过防火墙的 WCF wsHttpBinding 的有趣问题
我在互联网托管提供商中部署了一个 Web 应用程序。 此 Web 应用程序使用部署在我公司应用程序服务器上的 IIS 服务器上的 WCF 服务,为了对公司的数据库进行数据访问,出于安全原因,网络人员允许我通过防火墙公开此 WCF 服务。 图表看起来像这样。
[托管页面] ---> (互联网)---> |防火墙
<公共 IP>:
| ---> [带有 WCF 服务的 IIS]
:<端口-Y>
我还想使用 wsHttpBinding 来利用其安全功能,并加密敏感信息。
尝试后我收到以下错误:
异常详细信息:System.ServiceModel.EndpointNotFoundException: To 'http://:/service/WCFService.svc' 的消息不能 由于地址过滤器不匹配,在接收器处进行处理 端点调度程序。 检查发送者和接收者的 端点地址一致。
经过一些研究,我发现 wsHttpBinding 使用 WS-Addressing 标准,并阅读了该标准,我了解到 SOAP 标头已得到增强,可以包含“MessageID”、“ReplyTo”、“Action”和“To”等标签。
所以我猜测,由于客户端应用程序端点指定了防火墙 IP 地址和端口,并且服务以其不同于防火墙 IP 的内部网络地址进行回复,因此 WS-Addressing 会触发上述消息。 我认为这是一个非常好的安全措施,但在我的场景中并不是很有用。
引用 WS-Addressing 标准提交内容 (http://www.w3.org/Submission/ws -寻址/)
“由于目前广泛使用的网络技术范围广泛 (例如,NAT、DHCP、防火墙),许多部署无法分配 给定端点的有意义的全局 URI。 为了让这些“匿名” 端点发起消息交换模式并接收回复, WS-Addressing 定义了以下众所周知的 URI 供使用 无法拥有稳定、可解析的 URI 的端点。 http://schemas.xmlsoap.org/ws/2004/08/寻址/角色/匿名”
如何配置 wsHttpBinding 端点来寻址我的防火墙 IP 并忽略或绕过 SOAP 消息标头中“To”WS-Addressing 标记中指定的地址?我必须更改我的服务端点配置中的某些内容?
非常感谢
Marko 的
帮助和指导PS:虽然我找到了任何解决方案,但我使用 basicHttpBinding 当然绝对没有问题。
I have a web application deployed in an internet hosting provider. This web application consumes a WCF Service deployed at an IIS server located at my company’s application server, in order to have data access to the company’s database, the network guys allowed me to expose this WCF service through a firewall for security reasons. A diagram would look like this.
[Hosted page] ---> (Internet) ---> |Firewall
<Public IP>:<Port-X >
|
---> [IIS with WCF Service<Comp. Network Ip>:<Port-Y>
]
I also wanted to use wsHttpBinding to take advantage of its security features, and encrypt sensible information.
After trying it out I get the following error:
Exception Details: System.ServiceModel.EndpointNotFoundException: The
message with To 'http://:/service/WCFService.svc' cannot be
processed at the receiver, due to an AddressFilter mismatch at the
EndpointDispatcher. Check that the sender and receiver's
EndpointAddresses agree.
Doing some research I found out that wsHttpBinding uses WS-Addressing standards, and reading about this standard I learned that the SOAP header is enhanced to include tags like ‘MessageID’, ‘ReplyTo’, ‘Action’ and ‘To’.
So I’m guessing that, because the client application endpoint specifies the Firewall IP address and Port, and the service replies with its internal network address which is different from the Firewall’s IP, then WS-Addressing fires the above message. Which I think it’s a very good security measure, but it’s not quite useful in my scenario.
Quoting the WS-Addressing standard submission (http://www.w3.org/Submission/ws-addressing/)
"Due to the range of network technologies currently in wide-spread use
(e.g., NAT, DHCP, firewalls), many deployments cannot assign a
meaningful global URI to a given endpoint. To allow these ‘anonymous’
endpoints to initiate message exchange patterns and receive replies,
WS-Addressing defines the following well-known URI for use by
endpoints that cannot have a stable, resolvable URI.
http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"
HOW can I configure my wsHttpBinding Endpoint to address my Firewall’s IP and to ignore or bypass the address specified in the ‘To’ WS-Addressing tag in the SOAP message header? Or do I have to change something in my service endpoint configuration?
Help and guidance will be much appreciated.
Marko.
P.S.: While I find any solution to this, I’m using basicHttpBinding with absolutely no problem of course.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以尝试用以下方法装饰您的服务类:
You might try decorating your service class with:
处理此问题的更安全方法是将端点 ListenUri 设置为服务 Url,将端点 Address 设置为客户端发送消息的外部端点。 这样,服务“信任”仅定向到该地址的消息,而不仅仅是任何地址。
A safer way to handle this is to set the endpoint ListenUri to the service Url, and the endpoint Address to the external endpoint where clients send messages. This way the service "trusts" messages directed only to that address, not just ANY address.
我不知道米奇·贝克的解决方案,从未尝试过。 但这涉及修改生成的代码。 还有另一种方法可以解决这个问题。
我假设您使用 svcutil.exe 生成客户端代码,并提供指向防火墙的 MEX 地址。 当您执行此操作时,所需的所有配置都会添加到 App.config(或 Web.config)中。 但是,配置中的服务地址将指向真实的服务地址(因为在 WSDL 文件中服务的地址仍然是真实服务的地址)。
所以,我认为可以解决这个问题:
通过提供 MEX 地址生成客户端代码(例如:http://:Port-X/service/wcfservice.svc?wsdl)。 这将生成所有需要的配置。
调用客户端构造函数时,将防火墙的 URI 作为 EnpointAddress,并指定生成的配置的配置名称。 这样,客户端将发送一条消息,就像将其发送到服务一样,但发送到防火墙的地址:
client = new ServiceClient(endpointConfigName, new System.ServiceModel.EndpointAddress("http://:Port-X/service/wcfservice.svc"));
I don't know about the solution from Mitch Baker, never tried it. But this involves modifying the generated code. There is another way to get around that.
I assume that you generated client code using svcutil.exe, giving a MEX address that points to the firewall. When you do this, all the configuration needed is added to the App.config (or Web.config). However, the service's address in the configuration will point to the real service address (as in the WSDL file the address of the service sill be the real service's address).
So, what I think will solve this issue:
Generate client code by giving the MEX address (eg: http://:Port-X/service/wcfservice.svc?wsdl). This will generated all the needed configuration.
When invoking the client constructor, give the URI of the firewall as the EnpointAddress, and the configuration name of the generated configuration. This way, the client will send a message as if it was sending it to the service, but to the firewall's address:
client = new ServiceClient(endpointConfigName, new System.ServiceModel.EndpointAddress("http://:Port-X/service/wcfservice.svc"));