title: Error in WCF client consuming Axis 2 web service with WS-Security UsernameToken PasswordDigest authentication scheme
body: <p>I have a WCF client connecting to a Java based Axis2 web service (outside my control). It is about to have WS-Security applied to it, and I need to fix the .NET client. However, I am struggling to provide the correct authentication. I am aware that WSE 3.0 might make it easier, but I would prefer not to revert to an obsolete technology.</p>
  
  <p>Similar issues (unsolved), include <a href="https://stackoverflow.com/questions/886987/web-service-request-authentication">this</a>, <a href="https://stackoverflow.com/questions/2368131/wcf-configuration-for-soap-plain-text-password-authentication-over-ssl">this</a> and <a href="http://www.eggheadcafe.com/community/aspnet/2/10050148/consume-java-webservice-w.aspx" rel="nofollow noreferrer">this</a>. </p>
  
  <p>The SOAP message <strong>should</strong> look like this:</p>
  
  <pre><code>&lt;wsse:UsernameToken&gt;
    &lt;wsse:Username&gt;&lt;!-- Removed--&gt;&lt;/wsse:Username&gt; 
    &lt;wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"&gt;&lt;!-- Removed--&gt;&lt;/wsse:Password&gt; 
    &lt;wsse:Nonce&gt;&lt;!-- Removed--&gt;&lt;/wsse:Nonce&gt; 
    &lt;wssu:Created&gt;2010-05-28T12:50:33.675+01:00&lt;/wssu:Created&gt; 
  &lt;/wsse:UsernameToken&gt;
  </code></pre>
  
  <p>However, mine looks like this:</p>
  
  <pre><code>&lt;s:Header&gt;
  &lt;h:Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;/h:Security&gt;
  &lt;o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
  &lt;u:Timestamp u:Id="_0"&gt;
  &lt;u:Created&gt;2010-06-23T10:31:23.441Z&lt;/u:Created&gt;
  &lt;u:Expires&gt;2010-06-23T10:36:23.441Z&lt;/u:Expires&gt;
  &lt;/u:Timestamp&gt;
  &lt;o:UsernameToken u:Id="uuid-d329b3b2-6a1f-4882-aea6-ec6b8a492de7-1"&gt;
  &lt;o:Username&gt;
  &lt;!-- Removed--&gt;
  &lt;/o:Username&gt;
  &lt;o:Password&gt;
  &lt;!-- Removed--&gt;
  &lt;/o:Password&gt;
  &lt;/o:UsernameToken&gt;
  &lt;/o:Security&gt;
  &lt;/s:Header&gt;
  </code></pre>
  
  <p>My client looks like this:
  P.S. Note the <strong>required</strong> SecurityHeaderType param. What is that?</p>
  
  <pre><code>public MyAck SendRequest(MyRequest request)
  {
   RemoteServicePortTypeClient client = new RemoteServicePortTypeClient();
  
   client.ClientCredentials.UserName.UserName = "JAY";
   client.ClientCredentials.UserName.Password = "AND";
  
      // what is the difference between the two different Credential types??
      //client.ClientCredentials.HttpDigest.ClientCredential.UserName = "SILENT";
      //client.ClientCredentials.HttpDigest.ClientCredential.Password = "BOB";
  
   SecurityHeaderType sht = new SecurityHeaderType();
   //sht.Any = ???; // How do I use this???
   //sht.AnyAttr = ???; // How do I use this ???
  
   // SecurityHeaderType is a required parameter
   return client.RemoteServiceOperation_Provider(sht, request);
  }
  </code></pre>
  
  <p>Current binding is as follows:</p>
  
  <pre><code>&lt;basicHttpBinding&gt;
      &lt;binding name="CustomBinding"&gt;
          &lt;security mode="TransportWithMessageCredential"&gt;
              &lt;transport clientCredentialType="None"&gt;&lt;/transport&gt;
              &lt;message clientCredentialType="UserName" /&gt;
          &lt;/security&gt;
      &lt;/binding&gt;
  &lt;/basicHttpBinding&gt;
  </code></pre>
  
  <p>I've also tried a custom binding and got a similar error:</p>
  
  <pre><code>&lt;customBinding&gt;
    &lt;binding name="myCustomBindingConfig"&gt;
      &lt;security authenticationMode="UserNameOverTransport"
        messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11"
        securityHeaderLayout="Strict"
        includeTimestamp="false"&gt;&lt;/security&gt;
      &lt;textMessageEncoding messageVersion="Soap11"&gt;&lt;/textMessageEncoding&gt;
      &lt;httpsTransport /&gt;
    &lt;/binding&gt;
  &lt;/customBinding&gt;
  </code></pre>
  
  <p>And endpoint (Address obviously changed...):</p>
  
  <pre><code>&lt;endpoint address="https://www.somecompany.com/uat/axis/services/RemoteServiceOperation_Provider"
        binding="basicHttpBinding" bindingConfiguration="CustomBinding"
        contract="RemoteService.RemoteServicePortType"
        name="RemoteService_UAT" /&gt;
  </code></pre>
  
  <p>The custom fault that is being returned is as follows:</p>
  
  <pre><code>&lt;ErrorID&gt;0&lt;/ErrorID&gt;
  &lt;ErrorType&gt;UNEXPECTED&lt;/ErrorType&gt;
  &lt;ErrorDescription&gt;&lt;![CDATA[Array index out of range: 0]]&gt;&lt;/ErrorDescription&gt;
  &lt;TimeStamp&gt;2010-06-23T13:28:54Z&lt;/TimeStamp&gt;
  </code></pre>
  
  <p>I've read lots about custom headers, tokens, bindings and my brain is completely confused. Can anyone suggest a step by step process for sending the message in the right format?</p>
  
  <p><a href="http://msdn.microsoft.com/en-us/library/ms731872(VS.90).aspx" rel="nofollow noreferrer">This</a> appears to be the way forward for WCF, using custom tokens, but how should one apply the digest and nonce as required?</p>
  
  <p>Any help welcomed.</p>
  
  <h1>UPDATE</h1>
  
  <p>I've had some limited success. I've used the Microsoft.Web.Services3 library to create a UsernameToken with the correct digest. I've then created my own custom behavior and in the BeforeSendRequest method I've done the following to inject the header:</p>
  
  <pre><code>object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
  {
      UsernameToken ut = new UsernameToken("USERNAME", "PASSWORD", PasswordOption.SendHashed);
  
      XmlElement securityElement = ut.GetXml(new XmlDocument());
  
      MessageHeader myHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityElement, false);
      request.Headers.Add(myHeader);
  
      return Convert.DBNull;
  }
  </code></pre>
  
  <p>I add the behavior like so:</p>
  
  <pre><code>CustomBehavior behavior = new CustomBehavior("USERNAME", "PASSWORD");
  client.Endpoint.Behaviors.Add(behavior);
  </code></pre>
  
  <p>I can now see the headers going across:</p>
  
  <pre><code>&lt;s:Header&gt;
  &lt;Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
  &lt;wsse:UsernameToken wsu:Id="SecurityToken-c6aeb72d-4d36-4650-abd3-33cc66caac6d" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
  &lt;wsse:Username&gt;
  &lt;!-- Removed--&gt;
  &lt;/wsse:Username&gt;
  &lt;wsse:Password&gt;
  &lt;!-- Removed--&gt;
  &lt;/wsse:Password&gt;
  &lt;wsse:Nonce&gt;
  &lt;!-- Removed--&gt;
  &lt;/wsse:Nonce&gt;
  &lt;wsu:Created&gt;2010-06-24T16:23:58Z&lt;/wsu:Created&gt;
  &lt;/wsse:UsernameToken&gt;
  &lt;/Security&gt;
  &lt;/s:Header&gt;
  </code></pre>
  
  <p>But I'm getting the error:</p>
  
  <pre><code>&lt;soapenv:Fault&gt;
  &lt;faultcode xmlns=""&gt;soapenv:Server&lt;/faultcode&gt;
  &lt;faultstring xmlns=""&gt;WSDoAllReceiver: security processing failed; nested exception is: 
      org.apache.ws.security.WSSecurityException: General security error (WSSecurityEngine: Callback supplied no password for: USERNAME)&lt;/faultstring&gt;
  &lt;faultactor xmlns=""&gt;urn:Remote_Provider&lt;/faultactor&gt;
  &lt;detail xmlns=""&gt;
  &lt;CUSTOMError xmlns="urn:customerror:v01"&gt;
  &lt;ErrorID&gt;0&lt;/ErrorID&gt;
  &lt;ErrorType&gt;UNEXPECTED&lt;/ErrorType&gt;
  &lt;ErrorDescription&gt;&lt;![CDATA[WSDoAllReceiver: security processing failed; nested exception is: 
      org.apache.ws.security.WSSecurityException: General security error (WSSecurityEngine: Callback supplied no password for: USERNAME)]]&gt;&lt;/ErrorDescription&gt;
  &lt;TimeStamp&gt;2010-06-24T17:23:59Z&lt;/TimeStamp&gt;
  &lt;/CUSTOMError&gt;
  &lt;/detail&gt;
  &lt;/soapenv:Fault&gt;
  </code></pre>
  
  <p>There appears to be a missing <strong>Type</strong> attribute on the password node:</p>
  
  <pre><code>Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
  </code></pre>
  
  <p>However, I'm not sure if the security tracing and logging settings are blanket removing the attributes and content of those nodes. I've attempted to use the <a href="http://msdn.microsoft.com/en-us/library/ms730318.aspx" rel="nofollow noreferrer">logKnownPii</a> setting in the diagnostics logging, but the security information remains obscured. Any ideas on that one?</p>