WCF Net.tcp with sspi fails unless client and server using same windows Identity

16,329

Solution 1

Found the answer. My problem was a combination of two factors.

  1. When using the net.tcp binary WCF protocol, the Client Security Mode determines whether NTLM or Kerberos is used for authentication. If you set Client Security Mode to "Transport", Authentication uses NTLM and only one hop is possible. If you try to have the WCF Server talk to a third server, (like a database), it will fail. Using SecurityMode = "Message", otoh, causes the WCF server to use Kerberos, which allows multiple hops...

  2. The second issue was related to what I was doing on the client in the binding. WCF protocol net.tcp requires that when instantiating the endpoint on the client, you must specify an "endpoint identity" (see code below) . I had wrongly assumed this was somehow related to authentication, and was, therefore, the identity of the currently logged on user (Windows Principal) on the client.

        var epId = EndpointIdentity.CreateUpnIdentity(userPrincipalName);
        var ep = new EndpointAddress(new Uri(url), epId):
    

    No... The identity which must be specified in the creation of the endpoint on the client must be the identity the server is running under. This is why the code worked whenever I was logged on to the client with the same user as the service was running under, and failed when the client was a different user.

    I still do not understand why this user identity (of the service account) must be specified in the endpoint on the client. What function on the server is this data needed for?

Solution 2

Regarding the second point, the client is not required to run under the same Windows account of the server in order to be authenticated successfully, and it's not required to manually specify the account name in the request. From what I understand, WCF authentication is mutual, meaning the client is verifying the server as well.

The error you received is probably due to failure on the client side. If you configure the service endpoint of the client to provide a ServicePrincipalName, the problem might well be resolved. I found this article pretty helpful to solve the same issue I encountered.

Share:
16,329

Related videos on Youtube

Charles Bretana
Author by

Charles Bretana

Business Systems Analyst. Enterprise Systems Architect. Software developer. Custom applications framework design and implementation. Multi tier applications and database systems architectural design and implementation. Service oriented architecture (SOA) component design & development. Relational Database (schema) design and development. Microsoft dotNet applications design and development. Agile, SCRUM, & Waterfall SDLC Methodologies including Test Driven Development (TDD) and Unit Testing (NUnit) Education: BS Mathematics Steven Tech MBA Golden Gate University MSME Mechanical Engineering Boston University USAF F-4C/D/E Fighter Pilot, Retired; Civil Air Patrol; Owner operator Rutan Long EZ N974EZ;

Updated on August 22, 2022

Comments

  • Charles Bretana
    Charles Bretana over 1 year

    I have a WCF Service being hosted by a windows service. The client app succeeds if I log on to the client machine using the same credentials as the service is running under, but it fails with an exception if I am logged in with any other valid domain account.

    I have two accounts that I am testing with, one is an ordinary user account and the other account is an admin account. I have tried all four combinations listed below:

                       Server account
       CLient      RegUser    AdminAcct   
      RegUser     Succeeds      Fails   
     AdminAcct     Fails       Succeeds    
    

    As you can see it cannot be an admin issue as the system works when both client and server are running under the non-admin account. In both cases where it fails I get the same exception, on the client, with no indication of anything happening in the server logs:

    "A call to SSPI failed. see inner exception"

    The inner exception is "The target principle name is incorrect."

    I have registered the accounts as SPNs.

    The problem only occurs from my client app, but not when I use the WCVFTestClient.exe which ships with Visual Studio.

    The exception, in the WCF Trace log, is

    "System.ServiceModel.Security.SecurityNegotiationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    with a message:

    "Authentication failed on the remote side (the stream might still be available for additional authentication attempts)."

    The stack trace is at the bottom: What is wrong ?

    stack trace


    System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeAcceptor.OnAcceptUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity) System.ServiceModel.Channels.StreamSecurityUpgradeAcceptorBase.AcceptUpgrade(Stream stream) System.ServiceModel.Channels.InitialServerConnectionReader.UpgradeConnection(IConnection connection, StreamUpgradeAcceptor upgradeAcceptor, IDefaultCommunicationTimeouts defaultTimeouts) System.ServiceModel.Channels.ServerSessionPreambleConnectionReader.ServerFramingDuplexSessionChannel.OnOpen(TimeSpan timeout) System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) System.ServiceModel.Dispatcher.ChannelHandler.OpenAndEnsurePump() System.Runtime.ActionItem.DefaultActionItem.TraceAndInvoke() System.Runtime.ActionItem.CallbackHelper.InvokeWithoutContext(Object state) System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

  • Obl Tobl
    Obl Tobl over 6 years
    Thanks a lot for this answer. After hours and hours of try-and-error I tried this solution and it works like a charm! If we'll ever meet, I'll give you a beer ;-)
  • Charles Bretana
    Charles Bretana over 6 years
    You're very welcome! Where do I go to get my beer? <grin/>
  • Obl Tobl
    Obl Tobl over 6 years
    According to your profile I think we won't meet in near future...but never ending thanks will follow you ;-)
  • donovan
    donovan almost 6 years
    #2 is the main reason this failed. When using Windows auth the identity of the server is also validated. If you ran your service as SYSTEM or NETWORK SERVICE it could access the machine SPN and you shouldn't need to explicitly provide the UPN as it will default to expecting the machine SPN. Since you're running a custom account you need to tell your client about it so it can authenticate the server
  • donovan
    donovan almost 6 years
    #1 it's wrong to say you need message security to talk to a DB as those comms aren't using WCF. It may have a side effect of triggering Kerberos which maybe an issue for you. A better way to force Kerberos is to set AllowNtlm to false (google it).
  • AJ AJ
    AJ AJ over 5 years
    link isn't valid
  • Abner Escócio
    Abner Escócio about 5 years
    Thanks guy, you save my day!