Question

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.

Was it helpful?

Solution

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:

  • configure wsHttpBinding (which is rather "heavy-weight") to use no security at all, or to use username/password security which the callers would have to provide
  • use basicHttpBinding with no security instead (that's the ASMX model, basically)

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

OTHER TIPS

This gives you Transport level security with no authentication:

<configuration>  <system.serviceModel>
    <services>
      <service 
          name="Microsoft.ServiceModel.Samples.CalculatorService"
          behaviorConfiguration="CalculatorServiceBehavior">
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="Binding1" 
                  contract="Microsoft.ServiceModel.Samples.ICalculator" />
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>  </system.serviceModel>
</configuration>

For other scenarios I would have a look at the Microsoft WCF samples.

WCF can be a real pain when it comes to configuring it. Take a look at WCFSecurity it provides good working samples for different configuration environments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top