Axis security header - java

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

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.

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>

Related

How to add child elements in Soap Request XML using Java SAAJ

I want to add the child element(Identifier) in the body of the Soap Request as below:
Expected Soap Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="nsurl">
<soapenv:Header/>
<soapenv:Body>
<ns:GetRequest>
<ns:Identifier Type="x" Value="y"/>
</ns:GetRequest>
</soapenv:Body>
</soapenv:Envelope>
With my code I am able to add the child element(Identifier) as below:
Actual Soap Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="nsurl">
<soapenv:Header/>
<soapenv:Body>
<ns:GetRequest>
<ns:Identifier>Type="x" Value="y"</ns:Identifier>
</ns:GetRequest>
</soapenv:Body>
</soapenv:Envelope>
And here is the java code:
private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();
String myNamespace = "ns";
String myNamespaceURI = "nsurl";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("GetRequest", myNamespace);
SOAPElement soapBodyElem1 =soapBodyElem.addChildElement("Identifier", myNamespace);
soapBodyElem1.addTextNode("Type=\"x\" Value=\"y\"");
}
It appears that you are using SoapUI tool.
You could use Groovy Script test step with below script to change the same.
def xmlString = """ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="nsurl"> <soapenv:Header/> <soapenv:Body> <ns:GetRequest> <ns:Identifier>Type="x" Value="y"</ns:Identifier> </ns:GetRequest> </soapenv:Body> </soapenv:Envelope>"""
def xml = new XmlSlurper().parseText(xmlString)
//Get the Identifier node
def identifier = xml.'**'.find{it.name() == 'Identifier'}
//Create a map based on Identifier node value
def map = identifier.text().split(' ').collectEntries{ [(it.split('=')[0]) : it.split('=')[1].replace('"','')]}
//Remove the text value for Identifier node
identifier.replaceBody { '' }
//Set the attributes from the map
map.each{k,v -> identifier.#"$k" = v}
def newXml = groovy.xml.XmlUtil.serialize(xml)
log.info newXml
You can quickly try it online demo
In the expected request, Type and Value are attributes, not part of the content of the ns:Identifier element. Therefore you need to use SAAJ's addAttribute (or DOM's setAttributeNS) method to add them.

Adding customized SOAP Header in Java

I'm trying to get the desired customized header for my SOAP request:
What I need:
<soapenv:Header>
<urn:SessionHeader>
<urn:sessionId>abcdef1234</urn:sessionId>
</urn:SessionHeader>
</soapenv:Header>
But what I'm getting is:
<SOAP-ENV:Header>
<urn:sessionId xmlns:urn="www.dummy.com">
abcdef1234
</urn:sessionId>
</SOAP-ENV:Header>
I need to remove the xmlns from the childnode!
Below is the Java code I'm using:
SOAPHeader header = soapMessage.getSOAPHeader();
SOAPHeaderElement messageId = soapMessage.getSOAPHeader().addHeaderElement(new QName("www.dummy.com", "sessionId","urn"));
messageId.setTextContent("urn:abcdef1234");
Any suggestions on how to deal with this?
Yes, I managed to get a solution and it is working fine! #JimmyB
//SOAP Header
SOAPHeader header = soapMessage.getSOAPHeader();
SOAPHeaderElement sessionHeader = soapMessage.getSOAPHeader().addHeaderElement(new QName(serverM2M, "SessionHeader","urn"));
SOAPElement sessionID = sessionHeader.addChildElement(new QName(serverM2M, "sessionId","urn"));
sessionID.addTextNode(termTwo);
Which gives me an output:
<soapenv:Header>
<urn:SessionHeader>
<urn:sessionId>00D560000004Zxv!AQMAQGTYYqKa0NwwPNSY7QLnfn1aeyjsloOJQAvU4K53pJlPrGiI0rkdCfcEmN7va2c5caH3XmG.OvTxeU3hPAKwdlWxIlf8</urn:sessionId>
</urn:SessionHeader>

how to get child element from SOAP body?

How can I get clientCode from requestHeader which is located under SOAP body?
<soapenv:Body>
<ser:GS>
<!--Optional:-->
<requestHeader>
<!--Optional:-->
<req:clientCode>KL7MU</req:clientCode>
<!--Optional:-->
<req:clientUsername>BLABLA</req:clientUsername>
</requestHeader>
</ser:GS>
</soapenv:Body>
I try to get but iterator.hasNext() returns false.
SOAPBody soapBody = context.getMessage().getSOAPBody();
java.util.Iterator iterator = soapBody.getChildElements();
while (iterator.hasNext()) {
SOAPBodyElement bodyElement = (SOAPBodyElement) iterator.next();
String val = bodyElement.getValue();
System.out.println("The Value is:" + val);
}
You can use wsdl to generate java class:
wsimport stock.wsdl -b stock.xml -b stock.xjb
wsimport -d generated http://example.org/stock?wsdl
Then you can call SOAP services as local methods.
Some other tools:
wsdl2javawizard: http://sourceforge.net/projects/wsdl2javawizard/
apache cxf: http://cxf.apache.org/docs/wsdl-to-java.html
instead of getting form SOAP message body
try the child elements form SOAP message header like context.getMessage().getSOAPPart().getEnvelope().getHeader();
details :http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-client-side/
You can get the values like in axiom,
SOAPEnvelope mes = messageContext.getEnvelope();
SOAPHeader mesh = mes.getHeader();
SOAPBody mesb = mes.getBody();
OMElement messageId = mesh.getFirstChildWithName(new QName("http://www.w3.org/2005/08/addressing","MessageID"));
String messageIDStr = messageId.getText();
OMElement bodyChild = mesb.getFirstElement();
OMElement remoteAddress = bodyChild.getFirstChildWithName(new QName(
"http://YourNameSpaceURI",
"remoteAddress"));
String remoteAddressStr = remoteAddress.getText();

Axis2 "No WS-Security header found"

I'm trying to use axis2, but there must be Security headers in message.
I tried to add PEWSClientHeaderHandler class from this example, but it doesn't work (it works with default sun implementation, but not with axis2). The formed SOAP message looks like this:
...
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"></wsse:Security>
</soapenv:Header>
...
UsernameToken, Username and Password tags are missing (but again, they are set in code and no exception when using sun).
Can anyone provide the simplest example of how such a header can be set in axis2?
Axis2 implementation has 1 little difference:
Standard Sun implementation:
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPFactory soapFactory = SOAPFactory.newInstance();
SOAPHeader sh = envelope.addHeader();
SOAPElement wsSecHeaderElm = soapFactory.createElement("Security", AUTH_PREFIX, AUTH_NS);
SOAPElement userNameTokenElm = soapFactory.createElement("UsernameToken", AUTH_PREFIX, AUTH_NS);
SOAPElement userNameElm = soapFactory.createElement("Username", AUTH_PREFIX, AUTH_NS);
SOAPElement passwdElm = soapFactory.createElement("Password", AUTH_PREFIX, AUTH_NS);
userNameElm.addTextNode("username");
passwdElm.addTextNode("password");
userNameTokenElm.addChildElement(userNameElm);
userNameTokenElm.addChildElement(passwdElm);
wsSecHeaderElm.addChildElement(userNameTokenElm);
sh.addChildElement(wsSecHeaderElm);
Axis2 implementation:
// the same as above
userNameTokenElm.addChildElement(userNameElm);
userNameTokenElm.addChildElement(passwdElm);
SOAPElement el = sh.addChildElement(wsSecHeaderElm); // addChildElement returns new SOAPElement!
el.addChildElement(userNameTokenElm);
That's all

CXF Web-Services Response return invalid name

I used CXF WSDL2java to generate a server for an existing WSDL.
This gave me a SEI like that :
#WebService(targetNamespace = "http://mon.namespace.1", name = "MonWs")
#XmlSeeAlso({ObjectFactory.class})
public interface MonWs {
#WebResult(name = "Output", targetNamespace = "http://mon.namespace.1")
#RequestWrapper(localName = "maMethodePrincipale", targetNamespace = "http://mon.namespace.1", className = "MaMethodePrincipaleRequest")
#WebMethod(operationName = "maMethodePrincipale", action = "http://mon.namespace.1/MonWs/maMethodePrincipale")
#ResponseWrapper(localName = "maMethodePrincipaleResponse", targetNamespace = "http://mon.namespace.1", className = "MaMethodePrincipaleResponse")
public MaMethodePrincipaleResponse.Output maMethodePrincipale(
#WebParam(name = "Input", targetNamespace = "http://mon.namespace.1")
MaMethodePrincipaleRequest.Input Input
);
}
I created a basic implementation but when I call it on my server (hosted on tomcat, with de CXfNonSpringServlet) with soapUI (and other client) I got this kind of return :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:MaMethodePrincipaleResponse xmlns:ns1="http://mon.namespace.1">
<ns2:return xmlns="http://mon.namespace.2" xmlns:ns2="http://mon.namespace.1"/>
...
my return object field list correctly named
...
</ns2:return>
</ns1:MaMethodePrincipaleResponse>
</soap:Body>
</soap:Envelope>
my problem is the the tag "ns2:return ..." it should be name "Output" like I define in all the annotations (even in maMethodePrincipaleResponse name etc...)
So when i try to call my server with a java client I've got an error message like
javax.xml.bind.UnmarshalException: Unexpected Element (URI : "http://mon.namespace.1", local : "return"). Expected elements are <{http://mon.namespace.1}Output>
I already try a bunch of possible correction like set the soap binding to "bare" and set every partname or name to "Output" But nothing works.
What should i do to have this return parameter named "Output"?
You can try to use Interceptor.
in this link you can see how you can modify cxf response.
good luck
You are using Request/ResponseWrapper's. Thus, the names for the elements would be defined in the annotations on the fields in those classes.

Categories

Resources