Saturday, February 5, 2011

WCF service with multiple http-hosts

Introduction:

In the IIS configurations there is a section to configure which address are allowed to access the web-site in term of host-names.

For example, we can access our application in several ways:

http://IP/MyApp/My.aspx

http://server-name/MyApp/My.aspx

http://MyLoadBalancerName/MyApp/My.aspx

We can configure this in the IIS for our web-site:

On IIS 6:

right click on the web-site->properties-> web-site tab –> advanced

On IIS 7 and up:

right click on the web-site –> Edit bindings

image

*on IIS 7 on windows 7, as you can see the configuration is for all kinds of bindings, not just http.

The default is an empty host name => you can access any way you want. but you can set all kinds of host-names for all kind of ports. this way you are limiting the access to your site, and of course this is the best-practice for securing your site. usually we will configure our server-name and our load balancer server if we have one.

So what does WCF has to do with all of that??

Well, when you configure more that one host-name to a specific binding(let's say http) on your IIS and try to access a service on the site via that binding you'll get not-so-nice error that says that you have too many http-address but you only allowed to have one:

"This collection already contains an address with scheme http. There can be at most one address per scheme in this collection."

The solution is quiet simple – you can set an address filter in the server config that tells him to access the server with a specific address only. you can do this with baseAddressPrefixFilter:

<system.serviceModel>   
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://MyHostName"/>
<add prefix="net.tcp://MyHostName"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
........
</system.serviceModel>
In this case the wcf will try to access the specific address for the binding and will ignore all the other headers.
Some notes:
*If you want, there are other solutions that includes creating a serviceFactory to solve the problem.
*This is relevant for .net 3/3.5. in .net 4 there is a property called MultipleSiteBindingsEnabled that handles this issue, and by setting it to true you can freely use wcf with several http-hosts.

No comments:

Post a Comment