Access to security headers in JAX-WS custom handler
I want to implement custom handler that will check if request contains all required security headers.
The "head" part of the request looks as follows:
<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<header1>value of header one</header1>
<header2>value of header two</header2>
<wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>X</wsse:Username>
<wsse:Password>X</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
I tried to get access to the seciurity header and I can't.
First way which I tried was:
public class MyCustomHandler implements
SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext smc) {
SOAPMessage message = smc.getMessage();
SOAPHeader header = message.getSOAPHeader();
Iterator iterator = header.getChildElements();
while (iterator.hasNext()) {
SOAPElement element = (SOAPElement) iterator.next();
log.debug(element.getValue());
log.debug(element.getLocalName());
}
return true;
}
public boolean handleFault(SOAPMessageContext smc) {
logToSystemOut(smc);
return true;
}
public void close(MessageContext messageContext) {
}
...
Unfortunetaly the "while" loop logged only header1 and header2 but there is nothing about "Seciurity".
I tried also getChilds(Qname) but it also does not wor开发者_高级运维k.
You might want to try using the SOAPPart
of the message:
if (!((Boolean) messageContext.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue()) {
SOAPPart msg = messageContext.getMessage().getSOAPPart();
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
final Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
namespaceMap.put("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
NamespaceContext nsContext = new NamespaceContext() {
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
List<String> prefixes = new ArrayList<String>();
for (String url : namespaceMap.values()) {
if (url.equals(namespaceURI)) {
prefixes.add(url);
}
}
return prefixes.iterator();
}
@Override
public String getPrefix(String namespaceURI) {
return getPrefixes(namespaceURI).next();
}
@Override
public String getNamespaceURI(String prefix) {
return namespaceMap.get(prefix);
}
};
xPath.setNamespaceContext(nsContext);
String userName = (String) xPath.evaluate("/soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/wsse:Username/text()", msg,
XPathConstants.STRING);
String password = (String) xPath.evaluate("/soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/wsse:Password/text()", msg,
XPathConstants.STRING);
}
I also added a check for "only inbound" messages. You don't want to check for security-stuff on you replies I assume.
Does this work for you (I just typed this down. Didnt really test it so you might have a compile issue)?
精彩评论