开发者

Access to security headers in JAX-WS custom handler

开发者 https://www.devze.com 2023-03-11 03:21 出处:网络
I want to implement custom handler that will check if request contains all required security headers.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消