Interesting issue with WCF wsHttpBinding through a Firewall
Asked Answered
K

3

5

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.

Karsten answered 11/12, 2008 at 21:34 Comment(0)
D
7

You might try decorating your service class with:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
Darell answered 12/12, 2008 at 7:24 Comment(0)
W
4

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.

Womack answered 15/3, 2010 at 5:14 Comment(2)
+1 - However, I am still not clear how this will work for services deployed to multiple servers behind Load Balancers. I went through this great post from you already devproconnections.com/article/net-framework2/…Schaaff
This is the correct way to do it. Your network admin should direct the requests from firewall to the server that your service is hosted and you should define the listenUri in the web.config to respond the directed requests. I have many services hosted in multiple servers with load balancers configured like this. This configuration also works with SSL terminators.Trafficator
F
2

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:

  1. Generate client code by giving the MEX address (eg: http://:Port-X/service/wcfservice.svc?wsdl). This will generated all the needed configuration.

  2. 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"));

Formalin answered 12/12, 2008 at 8:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.