I have a class that implements the SOAPHandler interface. The handleMessage is defined as:
public boolean handleMessage(SOAPMessageContext context) {
SOAPMessage msg = context.getMessage();
SOAPPart part = msg.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
// add namespaces
SOAPElement envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-
// add the header with additional elements
Name qname = envelope.createName("Security", "sse", "http://example.com/security.xsd");
element = envelope.addHeader().addChildElement(qname);
qname = envelope.createName("mustUnderstand");
element.addAttribute(qname, "1");
qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd");
element = envelope.getHeader().addHeaderElement(qname);
element.addTextNode("user1");
qname = envelope.createName("Password");
element = envelope.getHeader().addHeaderElement(qname);
element.addTextNode("1234");
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
This generates the following message:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<S:Header>
<sse:Security xmlns:sse="http://example.com/security.xsd" mustUnderstand="1"/>
<sse:UsernameToken xmlns:sse="http://example.com/user.xsd">user1</sse:UsernameToken>
</S:Header>
<S:Body>
....The rest of the transaction
</S:Body>
</S:Envelope>
The problem is I need to generate a message with the following format:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<sse:Security soapenv:mustUnderstand="1" xmlns:sse="http://example.com/security.xsd">
<sse:UsernameToken wsu:Id="UsernameToken-9993341" xmlns:wsu="http://example.com/user.xsd">
<sse:Username>user1</sse:Username>
<sse:Password Type="http://example.com/password#PasswordText">1234</sse:Password>
</sse:UsernameToken>
</sse:Security>
</soapenv:Header>
<soapenv:Body>
....The rest of the transaction
</soapenv:Body>
</soapenv:Envelope>
The "mustUnderstand" attribute doesn't have the soapenv prefix, the sse:Security tag is closed right away instead of having the other tags as children, and the UserName isn't properly formatted as
<sse:Username>user1</sse:Username>
. How can I format the message properly using the SOAPElement methods? The biggest thing I need to know is how to properly next the tags inside of the Security tag and how to have the username/password tags properly formatted.
I've tried different combinations of the addHeaderElement and addChildElement methods, but I can't get it formatted properly and the javadocs don't give enough detail about what they will generate.
The SOAP envelope is specified using the ENV namespace prefix and the Envelope element. The optional SOAP encoding is also specified using a namespace name and the optional encodingStyle element, which could also point to an encoding style other than the SOAP one.
A SOAP message is encoded as an XML document, consisting of an <Envelope> element, which contains an optional <Header> element, and a mandatory <Body> element. The <Fault> element, contained in <Body> , is used for reporting errors.
SOAPEnvelope envelope = soapPart. getEnvelope(); You can now use the getHeader and getBody methods of envelope to retrieve its empty SOAPHeader and SOAPBody objects. SOAPHeader header = envelope.
Create a SOAP message to define the remote endpoint, WSDL, and authentication settings. Navigate to System Web Services > SOAP Message. Click New. Enter a Name to identify the SOAP message.
This is taken from my working handler. Hope it works for you.
public static final String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
public static final String PASSWORD_TEXT_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
public static final String WSSE_SECURITY_LNAME = "Security";
public static final String WSSE_NS_PREFIX = "wsse";
private String username;
private String password;
private boolean mustUnderstand = false;
public boolean handleMessage(SOAPMessageContext messageContext) {
Object bOutbound = messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (bOutbound == Boolean.TRUE) {
try {
if (username != null && username.length() != 0) {
addSecurityHeader(messageContext);
LOG.debug("Added security header");
} else {
LOG.debug("No username configured thus not adding a security header");
}
} catch (Exception e) {
LOG.error("Exception in handleMessage", e);
return false;
}
}
return true;
}
private void addSecurityHeader(SOAPMessageContext messageContext) throws SOAPException {
SOAPFactory sf = SOAPFactory.newInstance();
SOAPHeader header = messageContext.getMessage().getSOAPPart().getEnvelope().getHeader();
if (header == null) {
header = messageContext.getMessage().getSOAPPart().getEnvelope().addHeader();
}
Name securityName = sf.createName(WSSE_SECURITY_LNAME, WSSE_NS_PREFIX, WSSE_NS);
SOAPHeaderElement securityElem = header.addHeaderElement(securityName);
securityElem.setMustUnderstand(mustUnderstand);
Name usernameTokenName = sf.createName("UsernameToken", WSSE_NS_PREFIX, WSSE_NS);
SOAPElement usernameTokenMsgElem = sf.createElement(usernameTokenName);
Name usernameName = sf.createName("Username", WSSE_NS_PREFIX, WSSE_NS);
SOAPElement usernameMsgElem = sf.createElement(usernameName);
usernameMsgElem.addTextNode(username);
usernameTokenMsgElem.addChildElement(usernameMsgElem);
Name passwordName = sf.createName("Type", WSSE_NS_PREFIX, WSSE_NS);
SOAPElement passwordMsgElem = sf.createElement("Password", WSSE_NS_PREFIX, WSSE_NS);
passwordMsgElem.addAttribute(passwordName, PASSWORD_TEXT_TYPE);
passwordMsgElem.addTextNode(password);
usernameTokenMsgElem.addChildElement(passwordMsgElem);
securityElem.addChildElement(usernameTokenMsgElem);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With