WCF WSHttpBinding SOAP Security Negotiation Failed

42,892

Solution 1

To enable the Negotiate process to select the Kerberos protocol for network authentication, the client application must provide an SPN, a user principal name (UPN), or a NetBIOS account name as the target name. If the client application does not provide a target name, the Negotiate process cannot use the Kerberos protocol. If the Negotiate process cannot use the Kerberos protocol, the Negotiate process selects the NTLM protocol.

In cross-domain, kerberos has to be used. Since service is running as local system account, a SPN identity has to be used on the client side for the target name.

For more informaiton, read http://support.microsoft.com/kb/929650

Hope this helps!

Solution 2

You can opt for basic HTTP binding if WSHttpBinding is not an actual requisite. :)

Basic HTTP eliminates the <identiy> tag so UPN and SPN problems wouldn't occur.

Solution 3

I had the same issue and I tried almost all the settings in web.config and in the IIS server. And the best way for me is to set UPN when creating the client:

EndpointAddress endptAddress = 
               new EndpointAddress(
                  new Uri(your URL),
                  EndpointIdentity.CreateUpnIdentity("domain\username"));
Share:
42,892
naacal
Author by

naacal

Likes: C, C#, WPF, Silverlight, Java Dislikes: Linux, Richard Stallman, Open Source, PHP

Updated on July 09, 2022

Comments

  • naacal
    naacal almost 2 years

    I've got a fairly simple WCF self-hosted service using the WSHttpBinding that just refuses to work. If service and client runs on the same machine there's no problem, but as soon as I move the service to the window-server 2008 the client fails the communication attempts with

    EXCEPTION

    [System.ServiceModel.Security.SecurityNegotiationException] {"SOAP security negotiation with 'http://hvw-svr-01/SIT' for target 'http://hvw-svr-01/SIT' failed. See inner exception for more details."}

    INNER EXCEPTION

    [System.ComponentModel.Win32Exception] {"The Security Support Provider Interface (SSPI) negotiation failed. The server may not be running in an account with identity 'host/hvw-svr-01'. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server."}

    Since it's a self-hosted service I suppose I need to specify the UserPrincipalName, but no matter what I try for that property it just won't work.

    • domain\username
    • domain@username
    • host/localhost
    • host/hvw-svr-01
    • ... and so on

    Tried it with different user accounts aswell, including the built-in Administrator. If I try BasicHttpBinding instead of WSHttpBinding everything works as expected. I read tons of articles about that problem on google (and stackoverflow) but I still cannot figure what the problem is and how to specify that identity.

    Edit: Service App.Config

       <system.serviceModel>
      <services>
         <service name="SIT.Communication.Gate">
            <host>
               <baseAddresses>
                  <add baseAddress="http://localhost:2323/SIT" />
               </baseAddresses>
            </host>
            <endpoint address="" binding="wsHttpBinding" contract="SIT.Core.IGate">
               <identity>
                  <dns value="localhost"/>
                  <userPrincipalName value="XZDom\DGrain"/>
               </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
         </service>
      </services>
      <behaviors>
         <serviceBehaviors>
            <behavior>
               <serviceMetadata httpGetEnabled="True"/>
               <serviceDebug includeExceptionDetailInFaults="True" />
            </behavior>
         </serviceBehaviors>
      </behaviors>
    

    Edit: The Client itself is basically just this code fragment

            ChannelFactory<IGate> sitFactory = new ChannelFactory<IGate>(new WSHttpBinding(), new EndpointAddress("http://hvw-svr-01:2323/SIT"));
            IGate sitProxy = sitFactory.CreateChannel();
            bool pong = sitProxy.Ping(); <------ throws exception
    
    • Amar Palsapure
      Amar Palsapure over 12 years
      Can you post the configuration you used to host the service?
    • Amar Palsapure
      Amar Palsapure over 12 years
      If you remove idenity section altogether from your config, does it work?
    • naacal
      naacal over 12 years
      Nope does not work, already tried that (read somewhere on stackoverflow)
    • Richard Blewett
      Richard Blewett over 12 years
      are the machines in the same domain?
    • Richard Blewett
      Richard Blewett over 12 years
      also can you post the client's config so we can see what the client is expecting?
  • naacal
    naacal over 12 years
    Thank you that helped alot indeed. But why is my case exactly cross-domain? The self-hosted WCF app runs under an account that is member of our domain (the windows-server & client machine aswell). I tried providing a UPN at client configuration and it indeed worked, so that was definately the problem... but why do I have to do this? I would expect WCF to provide the UPN of the currently logged in user account per default if no one is provided.
  • Sentinel
    Sentinel about 12 years
    Very helpful answer. I have a similar problem. For some reason calling the WCF service using IP address allows NTLM and authentication succeeds. Using fully qualified domain name authentication fails with a "soap security negotation failed...etc" because I am not supply the UPN (I don't know how by config because the endpoint is an issuer endpoint in a federation scenario, and I can't see how to add the UPN to the issuer binding config)
  • Hand-E-Food
    Hand-E-Food about 11 years
    How do I opt for basic HTTP binding?
  • Jason Kleban
    Jason Kleban about 10 years
    @naacl - did you ever get enlightened on this topic? I'm struggling to understand my all-same-domain user account situation myself
  • Jason Kleban
    Jason Kleban about 10 years
    Oh, well I just realized for myself that my DNS host name was not correct. The host was reachable by the hostname I was using, but its default name, the one it presents itself as, was different. Using that correct one allowed me to skip the explicit spn business.
  • Hassan Boutougha
    Hassan Boutougha about 8 years
    Hi,by replacing your binding wsHttpBinding by a basicHttpBinding on client side and by exposing an endpoint with basicHttpBinding on service side