2012-02-20 17 views
15

Tôi cố gắng lấy thông tin từ dịch vụ web sử dụng loại WSS PasswordText. Thứ nhất, tôi thử nghiệm nó bằng soapUI và nhận dữ liệu thành công. Sau đó, tôi thực hiện chứng thực trên Java, viết SecurityHandler:SOAPFaultException "Tiêu đề MustUnderstand (ốc đảo-200401-wss-wssecurity-secext-1.0.xsd) không được hiểu"

public final class SecurityHandler implements SOAPHandler<SOAPMessageContext> { 

... 

@Override 
public boolean handleMessage(SOAPMessageContext messageContext) { 
    boolean outInd = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
    if (outInd) { 
     try { 
      WSSecUsernameToken builder = new WSSecUsernameToken(); 
      builder.setPasswordType(WSConstants.PASSWORD_TEXT); 
      builder.setUserInfo(_username, _password); 
      builder.addNonce(); 
      builder.addCreated(); 

      Document doc = messageContext.getMessage().getSOAPPart().getEnvelope().getOwnerDocument(); 
      WSSecHeader secHeader = new WSSecHeader(); 
      secHeader.insertSecurityHeader(doc); 
      builder.build(doc, secHeader); 
     } catch (Exception e) { 
      LOGGER.error("Unable to handle SOAP message", e); 
      return false; 
     } 
    } 
    return true; 
} 

... 
} 

Tôi đã kiểm tra đối tượng doc với XMLUtils.PrettyDocumentToString(doc) và thấy rằng nó trông thích XML gửi bởi soupUI - tất cả các thông tin xác thực (đăng nhập, mật khẩu, nonce và thời gian tạo) đang trên place, mustUnderstand thuộc tính của Security là đúng.

Sau đó, tôi phải đối mặt với lỗi:

javax.xml.ws.soap.SOAPFaultException: MustUnderstand tiêu đề: [{} http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd An] không hiểu

tôi thấy lời khuyên để loại bỏ mustUnderstand thuộc tính từ Security nhưng không hiệu quả. Bạn có bất cứ ý tưởng?

P.S.

Điểm cuối dịch vụ web là trên HTTPS.

Policy phần từ WSDL:

<wsp:Policy wsu:Id="BasicHttpBinding_RelateService_policy"> 
    <wsp:ExactlyOne> 
     <wsp:All> 
      <sp:TransportBinding> 
       <wsp:Policy> 
        <sp:TransportToken> 
         <wsp:Policy> 
          <sp:HttpsToken RequireClientCertificate="false"/> 
         </wsp:Policy> 
        </sp:TransportToken> 
        <sp:AlgorithmSuite> 
         <wsp:Policy> 
          <sp:Basic256/> 
         </wsp:Policy> 
        </sp:AlgorithmSuite> 
        <sp:Layout> 
         <wsp:Policy> 
          <sp:Lax/> 
         </wsp:Policy> 
        </sp:Layout> 
        <sp:IncludeTimestamp/> 
       </wsp:Policy> 
      </sp:TransportBinding> 
      <sp:SignedSupportingTokens> 
       <wsp:Policy> 
        <sp:UsernameToken 
          sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> 
         <wsp:Policy> 
          <sp:WssUsernameToken10/> 
         </wsp:Policy> 
        </sp:UsernameToken> 
       </wsp:Policy> 
      </sp:SignedSupportingTokens> 
      <sp:Wss10> 
       <wsp:Policy/> 
      </sp:Wss10> 
     </wsp:All> 
    </wsp:ExactlyOne> 
</wsp:Policy> 

soapUI yêu cầu:

<soapenv:Envelope xmlns:ns="http://api.example.com/RelateService/1.0" 
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header> 
     <wsse:Security soapenv:mustUnderstand="1" 
         xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:UsernameToken wsu:Id="UsernameToken-37" 
           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"> 
        password 
       </wsse:Password> 
       <wsse:Nonce 
         EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"> 
        li/0YK2wxrmrHL7Cg+etdQ== 
       </wsse:Nonce> 
       <wsu:Created>2012-02-21T08:59:10.262Z</wsu:Created> 
      </wsse:UsernameToken> 
     </wsse:Security> 
    </soapenv:Header> 
    <soapenv:Body> 
     <ns:RetrieveCustomerByEmail> 
      <ns:email>[email protected]</ns:email> 
      <ns:firstName/> 
      <ns:lastName/> 
     </ns:RetrieveCustomerByEmail> 
    </soapenv:Body> 
</soapenv:Envelope> 

Yêu cầu của tôi:

<?xml version="1.0" encoding="UTF-8"?> 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> 
    <S:Header> 
     <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
         xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
         S:mustUnderstand="1"> 
      <wsse:UsernameToken wsu:Id="UsernameToken-1"> 
       <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"> 
        password 
       </wsse:Password> 
       <wsse:Nonce 
         EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"> 
        +jeleKO9zr0/wLjAIYcmSg== 
       </wsse:Nonce> 
       <wsu:Created>2012-02-21T09:42:03.760Z</wsu:Created> 
      </wsse:UsernameToken> 
     </wsse:Security> 
    </S:Header> 
    <S:Body> 
     <ns5:RetrieveCustomerByEmail xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" 
            xmlns:ns2="http://schemas.datacontract.org/2004/07/XXX.Service" 
            xmlns:ns3="http://schemas.datacontract.org/2004/07/XXX.Service.Relate.Contract" 
            xmlns:ns4="http://schemas.datacontract.org/2004/07/XXX.Service.Dto" 
            xmlns:ns5="http://api.example.com/RelateService/1.0" 
            xmlns:ns6="http://schemas.microsoft.com/2003/10/Serialization/"> 
      <ns5:email>[email protected]</ns5:email> 
      <ns5:firstName/> 
      <ns5:lastName/> 
     </ns5:RetrieveCustomerByEmail> 
    </S:Body> 
</S:Envelope> 

Trả lời

7

Tôi tìm thấy giải pháp. phụ thuộc sau đây được yêu cầu:

<dependency> 
    <groupId>org.apache.cxf</groupId> 
    <artifactId>cxf-rt-frontend-jaxws</artifactId> 
    <version>2.2.3</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.cxf</groupId> 
    <artifactId>cxf-rt-transports-http</artifactId> 
    <version>2.2.3</version> 
</dependency> 

Tốt bài viết về chủ đề này và một số cạm bẫy của CXF: http://www.logicsector.com/java/how-to-create-a-wsdl-first-soap-client-in-java-with-cxf-and-maven/

+0

Tôi đã thử điều này và có ngoại lệ sau: 'Servlet/test thrrew load() ngoại lệ java.lang.ClassCastException: test.TestServiceListener không thể truyền vào javax.servlet.Servlet' – Jono

+1

chưa hiểu nguyên nhân và giải pháp. sao chép dán và nó hoạt động. yêu nó. ;) – iTake

13

Bạn có thể nhận được lỗi này khi dịch vụ không xử lý các tiêu đề. Dịch vụ cần thực hiện một SOAPHandler với một getHeaders() có thể giải quyết các tiêu đề. Đối với các lỗi nêu trên thực hiện đúng sẽ là như sau

@Override 
    public Set<QName> getHeaders() { 
     QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
       "Security"); 
     HashSet<QName> headers = new HashSet<QName>(); 
     headers.add(securityHeader);   
     return headers; 
    } 

Nó cũng có thể để có được điều này khi dịch vụ này được thực sự không an toàn, nhưng khách hàng đang cố gắng sử dụng cấu hình bảo mật (có thể sử dụng một an ninh XWSS cấu hình) Đối với điều này, chỉ cần kiểm tra wsdl đã xuất bản từ trình duyệt và đảm bảo nó chứa chính sách bảo mật dự kiến ​​(nối thêm wsdl vào URL điểm cuối)

Các vấn đề liên quan