WWSAPI to WCF interop 6: NetTcpBinding with transport security


NetTcpBinding provides a more efficient way to send/receive SOAP messages than HTTP does. The SOAP envelopes are transferred in binary format and an XML dictionary is built over the TCP session to help further reduce the payload size. NetTcpBinding supports all three security modes (message, transport, mixed) and can be used with no security as well. For transport security, both SSL and Windows SPNEGO are supported. Since SSL over TCP is not supported by WWSAPI in Win7, in this post I’ll focus on how to write a WWSAPI client to communicate with a WCF service using Windows security over TCP.


 


WS_TCP_SSPI_TRANSPORT_SECURITY_BINDING is the binding in WWSAPI for using Windows security over TCP. The following code snippet shows how to use it. Notice that you need to provide a credential even when you want to use the default credential.


 


    WS_DEFAULT_WINDOWS_INTEGRATED_AUTH_CREDENTIAL defaultCred = {};


    defaultCred.credential.credentialType = WS_DEFAULT_WINDOWS_INTEGRATED_AUTH_CREDENTIAL_TYPE;


 


    WS_SECURITY_BINDING_PROPERTY bindingProperties[1];


    ULONG bindingPropertyCount = 0;


    // Set a binding property to turn off server authentication.


    // Since the default setting is to require server authentication (which means Kerberos has to


    // be used), WsOpenServiceProxy will fail if NTLM is negotiated (as will be the case when


    // client and server are running on the server machine and client uses default credential).


    // In order to achieve server authentication, the client also needs to provide a correct SPN


    // (Service Principal Name). The SPN can be specified in WS_ENDPOINT_ADDRESS’s identity field.


    BOOL requireServerAuth = FALSE;


    bindingProperties[bindingPropertyCount].id = WS_SECURITY_BINDING_PROPERTY_REQUIRE_SERVER_AUTH;


    bindingProperties[bindingPropertyCount].value = &requireServerAuth;


    bindingProperties[bindingPropertyCount].valueSize = sizeof(requireServerAuth);


    bindingPropertyCount++;


 


    WS_TCP_SSPI_TRANSPORT_SECURITY_BINDING sspiBinding = {};


    sspiBinding.binding.bindingType = WS_TCP_SSPI_TRANSPORT_SECURITY_BINDING_TYPE;


    sspiBinding.clientCredential = &defaultCred.credential;


    sspiBinding.binding.properties = bindingProperties; // set the property array


    sspiBinding.binding.propertyCount = bindingPropertyCount; // set the property count


 


    WS_SECURITY_BINDING* bindings[1] = {&sspiBinding.binding};


 


    WS_SECURITY_DESCRIPTION securityDescription = {};


    securityDescription.securityBindings = bindings;


    securityDescription.securityBindingCount = WsCountOf(bindings);


 


    hr = WsCreateServiceProxy(


            WS_CHANNEL_TYPE_DUPLEX_SESSION,


            WS_TCP_CHANNEL_BINDING,


            &securityDescription,


            NULL,


            0,


            NULL,


            0,


            &serviceProxy,


            error);


 


Note: the corresponding WCF NetTcpBinding object is configured this way:


    NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);


    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;


 


In config file, the element is:


    <netTcpBinding>


        <binding name=windowsSecurity>


            <security mode=Transport>


                <transport clientCredentialType=Windows/>


            </security>


        </binding>


    </netTcpBinding>


 

Comments (4)

  1. Below you may links to resources available for connecting C/C++ code and Web Services using Windows Web

  2. lvogel says:

    Are there any benefits to using the WWSAPI vs. an IJW (native/managed c++ interop) scenario? Is the WWSAPI more performant than IJW?

  3. haoxu says:

    If your project can take dependency on .NET framework, you should probably use the offerings from WCF in .NET 3.0 and above. WWSAPI is mainly targeting applications with special requirements on memory footprint and performance. Yes, WWSAPI is more performant than the managed C++ interop.