26
votes

I need to connect to a WCF service from a native C++ application. I tried the link below and it worked with wsHttpBinding.

Create WCF service for unmanaged C++ clients

However I need to connect to a WCF service with a custom binding. This is how the code for the Custom Binding looks like in my app config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="ResourceCenterEndpoint5">
          <mtomMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
            messageVersion="Default" maxBufferSize="65536" writeEncoding="utf-8">
            <readerQuotas maxDepth="32" maxStringContentLength="8192"      maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          </mtomMessageEncoding>
          <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                    maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Ntlm"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    keepAliveEnabled="true" maxBufferSize="65536"
                    proxyAuthenticationScheme="Anonymous"
                    realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                    useDefaultWebProxy="true" />
        </binding>
      </customBinding>
      </binding>
    </bindings>
    <client>
      <endpoint address="http://usaabcxyzas1.na.abc.com/Build15/ReserSVC/Resource.svc"
      binding="customBinding" bindingConfiguration="ResourceCenterEndpoint5"
      contract="ServiceReference2.ResourceCenterServiceContract"
      name="ResourceCenterEndpoint5">
        <identity>
          <userPrincipalName value="[email protected]" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

I have a bridge DLL which is a managed C++ DLL. The managed C++ DLL connects the C# Client to the native appliaction. However I am unable to connect to the Web Service from the managed C++ DLL as the web service is using custom binding. The error I get is:

The http request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the sever was 'Negotiate,NTLM'

This is how I tried to connect to the Webservice from the manged C++ dll:

Binding^ binding = gcnew BasicHttpBinding();

EndpointAddress^ address = gcnew EndpointAddress(gcnew String("http://usaabcxyzas1.na.abc.com/Build15/ReserSVC/Resource.svc"));

HelloServiceClient::ServiceReference2::ResourceCenterServiceContractClient^ client = gcnew HelloServiceClient::ServiceReference2::ResourceCenterServiceContractClient(binding, address); 
client->DoWork();

So basically I need to connect the managed C++ dll to the WCF Service with custom binding. How can I do this?

6

6 Answers

2
votes

You are trying to use the BasicHttpBinding in your client code.

In the config file you require NTLM:

authenticationScheme="Ntlm"

The error points you to what you you have in the service's config file.

*The http request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the sever was 'Negotiate,NTLM'*

You also look like you've tried to hack in

proxyAuthenticationScheme="Anonymous"

So it comes down to your security requirements. If you want the service to not have security just take out the NTLM reference. If you want security you'll need a security section in your binding definition, something like:

            <security mode="TransportCredentialOnly">
              <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
              <message clientCredentialType="UserName" algorithmSuite="Default" />
            </security>

Look at this article for more

1
votes

I don't think you want custom binding, as much as you want to customize the out of the box bindings. Unless your intention was to create a propietary communication protocol, outside the the TCP/IP etc.

For the security issue, you would want to look into setting Security.Mode properties as well as assigning the right transport and/or message security properties. eg. use certificate or password challenge, encrypt, encrypt and sign etc.

You'll also need to do the same on the client side. The binding should be almost identical to that of the server side.

If you don't like basicHttp, there's always TCP, MSMQ, named piped and so on. You should look it up to get the full list.

1
votes

Have you tried to generate the WSDL from the web service using SvcUtil. Once you have the client proxy and the config which will have the configuration needed by client to connect to the service.

Also you did mention you want to connect using CustomBinding but in the client code you are using BasicHttpBinding.

One more thing you need your code it set is the AuthenticationScheme since the server is expecting scheme NTLM and your client code doesnt set that and by default it is Anonymous.

1
votes

This looks like an authentication error to me, so you need oto give yourself more permissions or find out who to get it but for example providing a user name and password.

1
votes

I maintain native c++ applications that consume Wcf services. Rather than deal with the raw connections and XML I will recommend using the excellent gSoap library. This takes the WSDL from a service and generates code to operate with it. By using the http://code.google.com/p/gsoapwininet/ plug-in all communication is directed via IE, which means that all the various windows authentication methods are automatically supported, which should solve your specific issue.

0
votes

You can create a customBinding and pass in the required binding configuration name.