3

I am trying to access a secure .NET SOAP webservice in an Android app, using the KSOAP2 library. I have checked for other answers on Stack Overflow, but so far none of them have helped me.

A username and password are required for authentication. The method also takes a String and returns a complex type. I have gotten this to work with an identical but unsecure service (ie, no username/password, but passing String and returning complex type works fine).

I can connect to the secure webservice using soapUI. All I have to do is give it the correct String parameter, set the username and password through the SoapUI request properties, and also set the WSS-PasswordType to "PasswordText".

I am confused about how to achieve this through my Java code. The SoapUI request (which works) looks like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>(my username) </wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">(my password) </wsse:Password>
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">eic5EdyTomcBLocwyph5Mw==</wsse:Nonce>
        <wsu:Created>2012-02-08T09:47:55.225Z</wsu:Created>
        </wsse:UsernameToken></wsse:Security>
    </soapenv:Header>
   <soapenv:Body>
      <tem:GetClientByNationalID>
          <!--Optional:-->
         <tem:nationalID>(the nationalID) </tem:nationalID>
      </tem:GetClientByNationalID>
   </soapenv:Body>
</soapenv:Envelope>

I figured I should be passing username and password in the Soap header then so I tried following this answer but this didn't work. I then used [Lalit's answer] (SOAP web service on android) below to edit the header of my request to try to make it identical to the SoapUI-generated request, but I am still getting the same error. Here is what my code is now producing:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
    <v:Header>
    <n0:Security mustUnderstand="1" xmlns:n0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <n0:UsernameToken n1:Id="UsernameToken-1" xmlns:n1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <n0:Username>(my username)</n0:Username>
            <n0:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">(mypassword)</n0:Password>
            <n0:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">eic5EdyTomcBLocwyph5Mw==</n0:Nonce>
            <wsu:Created>2012-02-08T09:47:55.225Z</wsu:Created>
        </n0:UsernameToken>
    </n0:Security>
</v:Header>
<v:Body>
    <GetClientByNationalID xmlns="http://tempuri.org/" id="o0" c:root="1">
        <nationalID i:type="d:string">(testnationalID)</nationalID>
    </GetClientByNationalID>
</v:Body>

This is the error I'm still getting in LogCat:

02-10 10:53:49.261: W/System.err(1187): javax.net.ssl.SSLHandshakeException:
java.security.cert.CertPathValidatorException: Trust anchor for certification path
not found.

This makes it look like a certificate issue, so I imported the cert from the server with InstallCert and verified with Keytool that it's in my keystore. This made no difference. On the other hand, I assume it's not a certificate issue since SoapUI worked before I had that cert installed.

Now I'm confused, so here are my questions:

1) Is adding the cert to the cacerts keystore in my JRE lib/security enough, or do I need to write some Java code to then access this cert?

2) Is this a cert issue at all, if SoapUI was able to connect successfully to the webservice without me installing the cert?

3) If it's not a cert issue, can anyone advise on what kind of code I need to use to produce a Soap request that will successfully authenticate and then execute the method call? I presume this is a case of getting my java-produced request to look as similar as possible to the SoapUI-generated request.

Community
  • 1
  • 1
breadbin
  • 584
  • 1
  • 11
  • 19
  • have you check these links [First](http://stackoverflow.com/questions/6441158/how-can-i-access-an-ssl-connection-through-android), [Second](http://stackoverflow.com/questions/6825226/trust-anchor-not-found-for-android-ssl-connection) – Lalit Poptani Feb 08 '12 at 12:46
  • I am not sure if those links apply when I am using KSOAP2 - do I still need to set up my SSL connection manually? – breadbin Feb 08 '12 at 14:05
  • @breadbin Hi, how did you added that – AndroidDev May 22 '14 at 10:15

2 Answers2

4

You can create the Header element and add the Authentication details,

Element[] header = new Element[1];
header[0] = new Element().createElement(NAMESPACE,"AuthHeader");

Add Username tag with username,

Element username = new Element().createElement(NAMESPACE, "username_tag");
username.addChild(Node.TEXT, "username_value");
header[0].addChild(Node.ELEMENT, username);

Add Password tag with password,

Element password = new Element().createElement(NAMESPACE, "password_tag");
password.addChild(Node.TEXT, "password_value");
header[0].addChild(Node.ELEMENT, password);

Add the header to the SoapSerializationEnvelope

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope
                                                                         .VER11);
envelope.dotNet = true;
envelope.headerOut = header;
envelope.setOutputSoapObject(request);
Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
  • I tried this and still get the same error. What about this line: (my password) ? I know that if I don't set the WSS-PasswordType to "PasswordText" then it doesn't work, so I imagine I need to do this in Java code somehow. Do you know how? – breadbin Feb 08 '12 at 12:57
  • Try [this](http://stackoverflow.com/questions/3564467/soap-wev-service-on-android) answer. – Lalit Poptani Feb 08 '12 at 17:04
  • Thanks for your answer @Lalit Poptani, but unfortunately I'm still getting the same error. I have updated my java-generated request above to show what I'm now producing, and it still isn't working. Any other ideas? – breadbin Feb 10 '12 at 10:59
  • Sorry, not much idea about it. – Lalit Poptani Feb 10 '12 at 11:03
  • @LalitPoptani I am getting this error In my webservice : org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG <{http://schemas.xmlsoap.org/wsdl/}wsdl:definitions name='hubbuchUser' targetNamespace='http://elofizetes.eszak.hu/soap/hubbuch/'>@4:98 in java.io.InputStreamReader@4205c058) – DearDhruv Feb 26 '14 at 11:28
  • Lalit Poptani: This is my web api link [http://182.19.20.182:81/mcommerce.webservices/pgService?wsdl](http://182.19.20.182:81/mcommerce.webservices/pgService?wsdl) can you tell me what is my AuthHeader name? – Harshal Kalavadiya Mar 02 '16 at 12:46
  • 1
    @LalitPoptani you saved my life. After a lot of things tried, this is the only thing that has worked. Thanks. – Borja Nov 10 '16 at 18:42
0

I hope it is not too late. Please have a look at the answer on the following link.

https://stackoverflow.com/a/17691465/2499764

I can share the code for constructing the header if you are still interested.

Community
  • 1
  • 1