Error in WCF client consuming Axis 2 Web service with ws-security UsernameToken passworddigest authentication scheme

Source: Internet
Author: User
Tags cdata

13down Votefavorite6

I have a WCF client connecting to a Java based AXIS2 Web service (outside my control). It is about to has 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.

Similar issues (unsolved), include this, this and this.

The SOAP message should :

<wsse:UsernameToken>  <wsse:Username><!-- Removed--></wsse:Username>   <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"><!-- Removed--></wsse:Password>   <wsse:Nonce><!-- Removed--></wsse:Nonce>   <wssu:Created>2010-05-28T12:50:33.675+01:00</wssu:Created> </wsse:UsernameToken>

However, mine looks like this:

  <s:header> 

My client looks like THIS:P.S. Note the required securityheadertype param. What's that?

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);}

Current binding is as follows:

<basicHttpBinding> <binding name="CustomBinding"> <security mode="TransportWithMessageCredential"> <transport clientCredentialType="None"></transport> <message clientCredentialType="UserName" /> </security> </binding></basicHttpBinding>

I ' ve also tried a custom binding and got a similar error:

<customBinding> <binding name="myCustomBindingConfig"> <security authenticationMode="UserNameOverTransport" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11" securityHeaderLayout="Strict" includeTimestamp="false"></security> <textMessageEncoding messageVersion="Soap11"></textMessageEncoding> 

and endpoint (Address obviously changed ...):

<endpoint address="https://www.somecompany.com/uat/axis/services/RemoteServiceOperation_Provider" binding="basicHttpBinding" bindingConfiguration="CustomBinding" contract="RemoteService.RemoteServicePortType" name="RemoteService_UAT" />

The custom fault is being returned is as follows:

<ErrorID>0</ErrorID><ErrorType>UNEXPECTED</ErrorType><ErrorDescription><![CDATA[Array index out of range: 0]]></ErrorDescription><TimeStamp>2010-06-23T13:28:54Z</TimeStamp>

I ' ve read lots about custom headers, tokens, bindings and my brain are completely confused. Can anyone suggest a step by step process for sending the message in the right format?

This appears to is the forward for WCF, using custom tokens, but how should one apply the digest and nonce as required ?

Any help welcomed.

UPDATE

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 do the following to inject the header:

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;}

I Add the behavior like so:

CustomBehavior behavior = new CustomBehavior("USERNAME", "PASSWORD");client.Endpoint.Behaviors.Add(behavior);

I can now see the headers going across:

<s:Header><Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><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"><wsse:Username><!-- Removed--></wsse:Username><wsse:Password><!-- Removed--></wsse:Password><wsse:Nonce><!-- Removed--></wsse:Nonce><wsu:Created>2010-06-24T16:23:58Z</wsu:Created></wsse:UsernameToken></Security></s:Header>

But I ' m getting the error:

  <soapenv:fault><faultcode xmlns= "" >soapenv:server</faultcode><faultstring xmlns= "" >wsdoallreceiver:security processing failed; Nested exception is:org.apache.ws.security.WSSecurityException:General security error (Wssecurityengine:callback su Pplied no password For:username) </faultstring><faultactor xmlns= "" >urn:remote_provider</faultactor ><detail xmlns= "" ><customerror xmlns= "URN:CUSTOMERROR:V01" ><ErrorID>0</ErrorID>< errortype>unexpected</errortype><errordescription><! [cdata[wsdoallreceiver:security processing failed; nested exception is:org.apache.ws.security.wssecurityexception:g Eneral Security Error (Wssecurityengine:callback supplied no password for:username)]]></errordescription> <timestamp>2010-06-24t17:23:59z</timestamp></customerror></detail></soapenv:fault  

There appears to is a missing Type attribute on the password node:

Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"

However, I ' m not sure if the security tracing and logging settings is blanket removing the attributes and content of thos E nodes. I ' ve attempted to use the LOGKNOWNPII setting in the diagnostics logging, but the security information remains obscured. Any ideas on that one?

C # WCF Web-services Axis2 ws-security
ShareImprove this question Edited June ' at 16:41 Asked June at 14:47junto7,579 7
Add a Comment
3 answersactiveoldestvotes
Up vote5down voteaccepted

I can confirm the UPDATE from my question actually works:

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;}

and the client:

CustomBehavior behavior = new CustomBehavior("USERNAME", "PASSWORD");client.Endpoint.Behaviors.Add(behavior);

The error message was unrelated. The security header works with a very simple basichttpbinding:

<basicHttpBinding>  <binding name="BasicSOAPBinding">      <security mode="Transport" />  </binding></basicHttpBinding>

Code sample of this in action can be found on my blog:http://benpowell.org/supporting-the-ws-i-basic-profile-password-dig est-in-a-wcf-client-proxy/

ShareImprove this answer Edited APR 2 ' + at 14:29 answered Jul at 16:35junto7,579 7
Add a Comment
Up vote2down vote

This question was well written--many thanks. In reference to @Junto's "How does I use this" comment, it turns out that the Securityheader param on the service method can be used to add the header. I ' ve included an example below. I believe that, what's happening is, the SvcUtil.exe tool is barfing when trying to read the ws* DTDs. The "Add Service Reference" wizard is not obvious. But it's very obvious when you run svcutil.exe from the command line. Because svcutil.exe fails to read the ws* DTD ' s, the Securityheader object was not well developed. But Microsoft gives a out with the. Any property. You can serialize the UsernameToken class right into the. Any property and your header would be added to the message. Again, thanks for this excellent question.

How to use the Securityheader parameter to add a UsernameToken security header:

Required Tools:

Fiddler2 (or similar)--you really can ' t figure any of the the without inspecting the HTTP headers.

Required Reference:

Microsoft.Web.Services3.dll -- you can reference this 2.0 framework assembly from your 4.0 assembly

WCF Service Call:

// Initialization of the service..._service = new MyService("MyEndpoint", RemoteUri);// etc.    // Calling the service -- note call to GetSecurityHeader()_service.ServiceAction(GetSecurityHeader(), "myParam1");// etc./// <summary>/// Construct the WSE 3.0 Security Header/// </summary>private SecurityHeader GetSecurityHeader(){    SecurityHeader h = new SecurityHeader();    UsernameToken t = new UsernameToken(RemoteLogin, RemotePassword, PasswordOption.SendPlainText);    h.Any = new XmlElement[1];    h.Any[0] = t.GetXml(new XmlDocument());    return h;}

App. Config:

  <system.serviceModel> <bindings> <basicHttpBinding> <binding name= "mybinding" CloseT            imeout= "00:01:00" opentimeout= "00:01:00" receivetimeout= "00:10:00" sendtimeout= "00:10:00" allowCookies= "false" Bypassproxyonlocal= "false" hostnamecomparisonmode= "StrongWildcard" maxbuffersize= "1048576" MaxBuffer Poolsize= "524288" maxreceivedmessagesize= "1048576" messageencoding= "Text" textencoding= "Utf-8" transfermode= "Bu Ffered "usedefaultwebproxy=" true "> <readerquotas maxdepth=" + "maxstringcontentlength=" 8192 "max Arraylength= "16384" maxbytesperread= "4096" maxnametablecharcount= "16384"/> <security mode= "Tr             Ansport "> <transport clientcredentialtype=" None "proxycredentialtype=" None "realm=" "/> <message clientcredentialtype= "UserName" algorithmsuite= "Default"/> </security> & Lt;/binding> </basichttpbinding> </bindings> <client> <endpoint address= "Http://myservice.com/service.asmx "Binding=" BasicHttpBinding "bindingconfiguration=" mybinding "contract=" Mycontract "Name=" M Yendpoint "/> </client> </system.serviceModel>
shareimprove this answer answered Sep "one at 12:41 brett4,849 2< Span class= "Badge2" >1530
Getsecurityheader () Did it for me, thanks! –robotron Apr at 13:44
Add a Comment
Up vote1down vote

I had a similar problem recently and gave up searching for a non-wse solution. After a couple days of pulling my hair out I ended downloading the WSE 3.0 SDK, generating a proxy class using Wsewsdl3.ex E, and creating a new policy for the UsernameToken. I was up and running in 15min. The following is currently working for me.

RemoteService service = new RemoteService();  //generated classUsernameToken token = new UsernameToken(username, password, PasswordOption.SendPlainText);Policy policy = new Policy();policy.Assertions.Add(new UsernameOverTransportAssertion());service.SetClientCredential(token);service.SetPolicy(policy);var result = service.MethodCall();
ShareImprove this answer answered June ' at 21:26

Error in WCF client consuming Axis 2 Web service with ws-security UsernameToken passworddigest authentication scheme

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.