views:

1495

answers:

3

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. Thanks

+1  A: 

WCF can be a real pain in the ass when it comes to configuring it. Take a look at http://www.codeplex.com/WCFSecurity it provides good working samples for different configuration environments.

Ray
Check out those blog posts I mentioned in my answer - they really help a lot and make WCF security as easy as picking one of those five scenarios - really! :-)
marc_s
Blog posts are ok, but they covering only basic cases. WCF Security Guidance is much more full and covering subject in deep.
Ray
Well, the point is: these blog posts cover the basic five scenarios which cover probably 90% of your use cases. The WCF Security Guidelines cover all possible combinations of features - but do you really need those? Since they cover EVERYTHING, this is a wealth of information you could possibly drown in.....
marc_s
+4  A: 

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

marc_s
+1  A: 

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>

For other scenarios I would have a look at the Microsoft WCF samples: http://www.microsoft.com/downloads/details.aspx?FamilyID=0043041F-95D6-4EB7-966A-C21A737E193A&amp;displaylang=en

Pawel Pabich