breadbin
breadbin

Reputation: 584

Authentication in KSOAP2 request to .NET webservice in Android

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.

Upvotes: 3

Views: 4771

Answers (2)

user2499764
user2499764

Reputation:

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.

Upvotes: 0

Lalit Poptani
Lalit Poptani

Reputation: 67296

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

Upvotes: 4

Related Questions