Tuesday, June 2, 2009

Multiple host headers / ssl / incorrect wsdl addresses using local machine

Came across an interesting scenario in deploying a wcf service that used transport security (ssl).

Symptoms:

Navigating to your WCF service in the browser shows you the wrong internal address.
You are trying to access your site as www.PublicAddress.com/MyService.svc and the page coming back tells you to run

svcutil.exe http://www.PrivateMachineName/MyService.svc

NOOooo you say. That's not what I want! Luckily the solution isn't that difficult but you do have several choices in increasing difficulty.


Solutions:
1. Set host header
This method is the quickest but you have to be aware of a couple situations.
a. You are not using ssl - Simply go into IIS (Im assuming 6 for this posting) and right click on your site, then click "advanced" to add the host headers. Typical scenarios have it configured as "All unassigned addresses" to port 80. Or a specific IP address assigned to port 80, with no host header listed. If either of these fit your case, just click "edit" and add your host name such as www.PublicSite.com
NOTE: If you already have a host header listed or need two host headers, which is very common for sites (such as www.publicsite.com and publicsite.com) WCF will fail when you try to run your service with:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.

You CANNOT by default start a wcf service with multiple host names bound to an address. Doh! If you must add multiple hosts to your site, then you cannot use this method. In that case it may make sense to create another site in IIS that responds to a different host header. Such as services.publicsite.com and you can add your host header to iis for that new site, update your web.config if necessary to fit the new address (if you have specified an identity in your web.config then change it, if not then your service will figure out what the proper identity is). For example you only need to update your config if the following case fits or you need ssl on your site and need to modify the element

<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="www.publicsite.com"/>
</identity>



Now, if you are using ssl it becomes a tiny bit trickier. You see adding the host header to port 80 binding in iis like we did above does not apply to ssl. You must specifically add the host header for ssl using the adsutil.vbs script usually located at c:\inetpub\adminscripts
if it is not there and it was possibly removed and you don't feel like installing it sometimes it can be found on a server at %SYSTEMROOT%\ServicePackFiles\i386

You can add host headers for port 80 here as well, so lets go over both.

1. If you are running more than one site on the machine verify the site id to use in the scripts by running:




2. Try binding filter
3. Implement custom factory
4. Avoid the whole problem and use restful services
5. Implement with web services and let IIS fully handle ssl without worrying about multiple bindings. If you required authentication use basic authentication over ssl configured in IIS. If you don't want to use windows accounts for basic authentication you can implement a custom basic auth provider, such as shown here on codeplex: http://www.codeplex.com/CustomBasicAuth

#4 was recommended to us, but if you've already developed the service then its not the best solution imho since there are relatively easy ways

2 comments: