WCF Security shouldn't be that difficult, but I've recently run into some problems that just couldn't be forseen (at least for me).
I have a WCF Service hosted in IIS - I have set IIS to Require secure channel (SSL) traffic and set the virtual directory security to Integrated Windows authentication only.
In my WCF Service web.config, I use the following binding configuration:
<bindings>
<basichttpbinding>
<binding name="SecureTransport">
<security mode="Transport">
<transport clientcredentialtype="Windows">
</transport>
</security>
</binding>
</basichttpbinding>
The security mode of
Transport is for communication over SSL. The client credential type of
Windows is for Integrated Windows authentication.
This should work fine, right? Well, it did on one test box, but on another I had a number of problems, each outline below.
I would normally use a browser to test the connection first.
Error: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.Even if IIS is configured for Integrated Windows authentication only and your service configuration specifies Windows as the client configuration, you get the following error in your browser:
Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.If this error is returned and Windows Authentication has been enabled in IIS, it means there is an issue with the supported network authentication schemes for the website that the web service is installed under. The most likely cause is that it is configured for NTLM only. We want to specify NTLM and Negotiate.
The following Microsoft KB article describes how to enable both schemes:
http://support.microsoft.com/kb/215383After this has been done IIS will need to be restarted, or the web service application will need restarting (load the web.config file and save without changing anything).
It would appear that the Windows credential setting in WCF .NET maps directly to the Negotiate scheme in IIS.
Error: Could not establish trust relationship for the SSL/TLS secure channel with authority.
The certificate is not fully trusted. This is likely to be a temporary certficate or a locally issued certficate that the client machine does not trust.
The following client config change will ignore this particular certficate error:
<system.net>
<settings>
<servicePointManager checkCertificateName="false" checkCertificateRevocationList="false" />
</settings>
</system.net>
Error: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate.
This appears to be an issue with .NET 3.5 SP1 (I say 'appears' as my only reference is a blog entry).
See this article: http://msmvps.com/blogs/alvin/archive/2008/11/14/net-3-5-sp1-breaking-change-to-wcf.aspx
The following client configuration change (for each endpoint) resolves this:
<system.serviceModel>
<client>
<endpoint address=... >
<identity>
<servicePrincipalName value="spn" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Note that the value of servicePrincipalName is not important.
Error: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
This error occurs when there are multiple entries for the Website Identification - it tries to create multiple service base addresses for each endpoint.
You can specify a filter in the server configuration to resolve this.
Here is an example:
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://tstmachine:80"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>