Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Axis security header

Hi trying to generate a security header in a Java Axis2 Client program in the format of.

<soapenv:Header>
 <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext>
  <wsse:UsernameToken>
   <wsse:Username>myUsername</wsse:Username>
   <wsse:Password>myPassword</wsse:Password>
  </wsse:UsernameToken>
 </wsse:Security>
</soapenv:Header>

using the following code

SOAPHeaderElement wsseSecurity = new SOAPHeaderElement(new PrefixedQName("http://schemas.xmlsoap.org/ws/2002/04/secext","Security", "wsse"));
MessageElement usernameToken = new MessageElement("", "wsse:UsernameToken");
MessageElement username = new MessageElement("", "wsse:Username");
MessageElement password = new MessageElement("", "wsse:Password");
username.setObjectValue(myProps.getProperty("username"));
usernameToken.addChild(username);
password.setObjectValue(myProps.getProperty("password"));
usernameToken.addChild(password);
wsseSecurity.addChild(usernameToken);

BookingPort bp = bsl.getBooking();
((Stub) bp).setHeader(wsseSecurity);

Unfortunately its not generating quite what I wanted and I get.

<soapenv:Header>
 <wsse:Security soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
  <wsse:UsernameToken xmlns:wsse="">
   <wsse:Username xmlns:wsse="">myUsername</wsse:Username>
   <wsse:Password xmlns:wsse="">myPassword</wsse:Password>
  </wsse:UsernameToken>
 </wsse:Security>
</soapenv:Header>

The service on the other end doesn't seem to handle the extra bits, resulting in an error

faultDetail:
        {http://xml.apache.org/axis/}stackTrace:com.ctc.wstx.exc.WstxParsingException: Non-default namespace can not map to empty URI (as per Namespace 1.0 # 2) in XML 1.0 documents
 at [row,col {unknown-source}]: [1,450]

How do I generate the SOAPHeader to not print out all the extra empty bits? Cheers

like image 593
yurl Avatar asked Jul 01 '10 08:07

yurl


2 Answers

You're passing an empty string as the first argument to MessageElement, and you need to pass null. Note that null and the empty string ("") are not the same thing in Java. Also, you are really cheating by passing the namespace prefix to the local name (second) parameter of the MessageElement constructor...this is not what it is designed for. That being said, you can fix the problem by passing null as the namespace (first) parameter. If you try to pass it directly, you'll likely get an ambiguous constructor error, so do something like the following:

SOAPHeaderElement wsseSecurity = new SOAPHeaderElement(new PrefixedQName("http://schemas.xmlsoap.org/ws/2002/04/secext","Security", "wsse"));
String nullString = null;
MessageElement usernameToken = new MessageElement(nullString, "wsse:UsernameToken");
MessageElement username = new MessageElement(nullString, "wsse:Username");
MessageElement password = new MessageElement(nullString, "wsse:Password");
username.setObjectValue(myProps.getProperty("username"));
usernameToken.addChild(username);
password.setObjectValue(myProps.getProperty("password"));
usernameToken.addChild(password);
wsseSecurity.addChild(usernameToken);

BookingPort bp = bsl.getBooking();
((Stub) bp).setHeader(wsseSecurity);

I'd also recommend you use a different web service engine (not Axis2) if you have any choice in the matter.

like image 101
Justin Garrick Avatar answered Oct 06 '22 00:10

Justin Garrick


Try this way to create custom header with Axis 1.* (The above code doesnt look like with Axis2)

import org.apache.axis.message.SOAPHeaderElement;
import javax.xml.soap.SOAPElement;


public void createCustomHeader(){

SOAPElement oHeaderElement;
SOAPElement oElement;   

    oHeaderElement = new SOAPHeaderElement("http://ws.mycompany.com", "securityHeader");
    oHeaderElement.setPrefix("sec");
    oHeaderElement.setMustUnderstand(false);

    oElement = oHeaderElement.addChildElement("username");
    oElement.addTextNode("myusername");
    oElement = oHeaderElement.addChildElement("password");
    oElement.addTextNode("mypassword");

    // You can create client code something like this..
    MySampleServiceServiceLocator service  = new MySampleServiceServiceLocator();
    service.setMySampleServiceEndpointAddress("endpointURL");
    MySampleWebService serv = service.getMySampleService();
    MySampleServiceSoapBindingStub stub = (MySampleServiceSoapBindingStub)serv;

    // add this header to your stubs
stub.setHeader(oHeaderElement);


// Finally call your web service methid
serv.getMyClaimStatus("XYZ001");


}

//It creates the custom header like this:

<soapenv:Header>
    <sec:securityHeader xmlns:sec="http://ws.mycompany.com"
        soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0">
        <sec:username>myusername</sec:username>
        <sec:password>mypassword</sec:password>
    </sec:securityHeader>
</soapenv:Header>
like image 44
HariKrishna Avatar answered Oct 06 '22 01:10

HariKrishna