在JAX-WS自定义处理程序中访问安全标头

时间:2011-06-08 18:01:40

标签: header jax-ws handler

我想实现自定义处理程序,它将检查请求是否包含所有必需的安全标头。

请求的“head”部分如下所示:

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

我试图访问seciurity标题但我不能。

我尝试的第一种方式是:

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) {
  }

...

不幸的是,“while”循环只记录了header1和header2,但没有关于“Seciurity”的内容。

我也试过getChilds(Qname),但它也不起作用。

1 个答案:

答案 0 :(得分:0)

您可能想尝试使用邮件的SOAPPart

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);
}

我还添加了“仅入站”消息的检查。您不希望在我认为的回复中检查安全性。

这对你有用吗(我只是输入了它。没有真正测试它,所以你可能有编译问题)?