Axis2客户端引发AxisFault:必须理解标题安全检查失败

时间:2018-01-08 22:04:05

标签: java web-services client axis2

我使用Axis2-1.6.1并且能够成功发送SOAP请求。以下是请求的示例:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
  <soapenv:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true">
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>***username***</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">***pass***</wsse:Password>
        <wsse:Nonce Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">***nonce***</wsse:Nonce>
        <wsu:Created Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">***datetime***</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>
    <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://mysite/contract/users/v3/IUsers/EchoAuthenticated</wsa:Action>
  </soapenv:Header>
  <soapenv:Body>
    <ns6:EchoAuthenticated xmlns:ns6="http://mysite/contract/users/v3">
      <ns6:value>success</ns6:value>
    </ns6:EchoAuthenticated>
  </soapenv:Body>
</soapenv:Envelope>

收到回复后,抛出此异常:

  

org.apache.axis2.AxisFault:必须了解标题http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd检查失败:安全性

在进行一些研究之后,我认为Axis2不喜欢的回答中有一些东西。困惑,我复制了上述请求并将其粘贴到SoapUI中并解雇了它。它有效,我收到以下回复。我还确认,使用Fiddler,这是我在Eclipse中发送此请求时得到的相同响应,它就是Axis2不喜欢客户端,也许是mustUnderstand吗? / p>

以下是回复:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://mysite/contract/users/v3/IUsers/EchoAuthenticatedResponse</a:Action>
    <a:RelatesTo>urn:uuid:***guid***</a:RelatesTo>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="_0">
        <u:Created>***datetime***</u:Created>
        <u:Expires>***datetime***</u:Expires>
      </u:Timestamp>
    </o:Security>
  </s:Header>
  <s:Body>
    <EchoAuthenticatedResponse xmlns="http://mysite/contract/users/v3">
      <EchoAuthenticatedResult>This is the Users service answering back. The value you sent was: success</EchoAuthenticatedResult>
    </EchoAuthenticatedResponse>
  </s:Body>
</s:Envelope>

我有能力转移到更新版本的Axis2,因为它与产品捆绑在一起,但我需要了解如何通过此错误。

1 个答案:

答案 0 :(得分:2)

我找到了一个解决方案,即在 false

的响应中设置 mustUnderstand 实例

要做到这一点,我已经完成了以下工作:

  1. 创建一个扩展* org.apache.axis2.handlers.AbstractHandler

  2. 的Handler类
      

    MustUnderstandHandler.java

    import java.util.Iterator;
    
    import org.apache.axiom.soap.SOAPEnvelope;
    import org.apache.axiom.soap.SOAPHeader;
    import org.apache.axiom.soap.SOAPHeaderBlock;
    import org.apache.axis2.AxisFault;
    import org.apache.axis2.context.MessageContext;
    
    public class MustUnderstandHandler extends org.apache.axis2.handlers.AbstractHandler  {
    
      @Override
      public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {
    
        try{
    
          System.out.println("RemoveMustUnderstandAll: invoke " + messageContext);
    
          SOAPEnvelope env = messageContext.getEnvelope();
          SOAPHeader header = env.getHeader();
    
          if(header != null){
    
              for(Iterator<?> itr = header.getChildElements(); itr.hasNext();){
    
                  SOAPHeaderBlock headerBlock = (SOAPHeaderBlock) itr.next();
    
                  if(headerBlock.getMustUnderstand()){
    
                    headerBlock.setMustUnderstand(false);
                    System.out.println("RemoveMustUnderstandAll (" + messageContext + "): setMustUnderstand(false) to " + headerBlock.getQName());
                  }
              }
          }
        }
        catch(Exception e){
    
          System.out.println(e.toString());
        }
    
        return InvocationResponse.CONTINUE;
      }
    }
    
    1. 连接AxisConfiguration以使用处理程序类

    2. 在生成的Stub(从WSDL2Java创建)中,我找到了执行客户端的实例,在这些行之前,我包括以下内容:

        

      MyStub.java

      AxisConfiguration axisConfiguration = _messageContext.getConfigurationContext().getAxisConfiguration();
      ArrayList arrayList = new ArrayList();
      arrayList.add(new MustUnderstandHandler());
      axisConfiguration.setInPhasesUptoAndIncludingPostDispatch(arrayList);
      
      // execute the operation client
      _operationClient.execute(true);