I have a very simple WCF service that I would like to expose publicly. I created the service and set it up over our server without much hassle. The problem is that we are able to use the service from within our private network, but when we attempt to use it from outside the network, the following error is throw:
The Security Support Provider Interface (SSPI) negotiation failed.
I did a little research and it sounds like WCF uses Windows Authentication by default. I'd like to change it to use no authentication, but I'm not entirely sure how. Here's how my config looks now.
<system.serviceModel>
<services>
<service behaviorConfiguration="XX.ZZ.WebService.MyServiceBehavior"
name="XX.ZZ.WebService.MyService">
<endpoint address="" binding="wsHttpBinding" contract="XX.ZZ.WebService.IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="XX.ZZ.WebService.MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I would appreciate some pointers, or nudges in the right direction.
Well, your service uses the wsHttpBinding, which by default will require Windows user credentials - which your external users obviously won't have. It's not WCF in itself that uses Windows credentials by default (as you state), but really this particular binding (wsHttpBinding) - others might default to other settings.
You have a couple of choices:
To turn off security completely from wsHttpBinding, include this in your config:
<bindings>
<wsHttpBinding>
<binding name="NoSecurity">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
and then configure your endpoints to use that binding configuration:
<system.serviceModel>
<services>
<service name="XX.ZZ.WebService.MyService"
behaviorConfiguration="XX.ZZ.WebService.MyServiceBehavior">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="NoSecurity"
contract="XX.ZZ.WebService.IMyService">
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
You could do the same with <basicHttpBinding>
instead of <wsHttpBinding>
if you wish (there's no benefit in using wsHttpBinding vs. basicHttpBinding, if you turned off security and all other more advanced features that wsHttpBinding offers).
There's also a really good blog post series that talk about the basics of WCF security in terms of five different, typical scenarios - excellent read!
Marc