Search code examples
wcf-bindingwcf-security

Use Both Certificate and User/Pass to Consume Java Web Service From .Net


I have a .Net c# client that needs to consume a Java web service from a third party. They require both a client cert and user name and password. I have the cert set up but constantly get 401 Unauthorized because I don't think the username and password are actually being attached to the request. It seems like WCF expects one or the other but not both cert and username/password. Surely I'm missing something.

<bindings>
<binding name="CC2WebSoap">
  <security mode="Transport">
    <transport clientCredentialType="Certificate" />
  </security>
</binding>
</bindings>
<client>
      <endpoint address="https://url_goes_here.com"
                binding="basicHttpBinding" 
                bindingConfiguration="CC2WebSoap"
                contract="acontract" 
                name="CC2WebSoap" 
                behaviorConfiguration="SecureClientBehavior"/>
</client>
 <behaviors>
      <endpointBehaviors>        
        <behavior name="SecureClientBehavior">
          <clientCredentials>
            <clientCertificate findValue="mythumbprint" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

     try
            {
        CC2WebSoap client= new CC2WebSoapClient("CC2WebSoap");
                client.ClientCredentials.UserName.UserName = "username";
                client.ClientCredentials.UserName.Password = "password";

                request = BuildRequest();

                response = client.DoSomething(request);
}
catch(Exception e){ // Always get 401 exception here. }

Solution

  • This turned out to be reasonably simple by adding a MessageInspector and the related classes to get WCF to attach the username and password to the headers before each request. Specifically, I followed the advice in the blog post below exactly.

    Using a MessageInspector To modify HTTP Headers