2012-02-20 19 views
15

Próbuję uzyskać informacje z usługi internetowej, która używa typu WSS typu PasswordText. Najpierw testuję go przy użyciu soapUI i pomyślnie dostaję dane. Potem realizowane uwierzytelnianie na Java, pisanie SecurityHandler:SOAPFaultException "Nie zrozumiano nagłówków MustUnderstand (oasis-200401-wss-wssecurity-secext-1.0.xsd)"

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

... 
} 

Sprawdziłem obiekt doc z XMLUtils.PrettyDocumentToString(doc) i zobaczył, że to wygląda lubi XML wysłana przez soupUI - wszystkie informacje uwierzytelniania (login, hasło, identyfikator jednorazowy i stworzyli razem) były na miejsce, mustUnderstand atrybut Security znacznik był prawdziwy.

Następnie wobec błędu:

javax.xml.ws.soap.SOAPFaultException: MustUnderstand nagłówki [{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd} zabezpieczenia] nie są rozumiane

I znaleziono Uwagi do usuwania mustUnderstand atrybutu z Security tag, ale to nie pomaga. Czy masz jakies pomysły?

P.S.

Punkt końcowy usługi WWW znajduje się na HTTPS.

część Policy z 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> 

prośba SoapUI:

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

Moja prośba:

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

Odpowiedz

7

znalazłem rozwiązanie. zobowiązane były następujące zależności:

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

dobry artykuł na ten temat, a niektóre pułapki CXF: http://www.logicsector.com/java/how-to-create-a-wsdl-first-soap-client-in-java-with-cxf-and-maven/

+0

Próbowałem tego i otrzymałem następujący wyjątek: 'Serwlet/test rzucił wyjątek load() wyjątek java.lang.ClassCastException: test.TestServiceListener nie można przesłać do javax.servlet.Servlet' – Jono

+1

nie zrozumieli przyczyny ani rozwiązania. kopia wklejona i działa. kocham to. ;) – iTake

13

Można dostać ten błąd, gdy usługa nie obsługuje nagłówki. Usługa musi zaimplementować SOAPHandler z getHeaders(), który mógłby rozwiązać nagłówki. Na powyższej usterki prawidłowa realizacja byłaby następująco

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

Jest również możliwe, aby dostać to, gdy usługa nie jest właściwie zabezpieczyć, ale klient próbuje użyć konfiguracji zabezpieczeń (ewentualnie stosując zabezpieczenia XWSS W tym celu wystarczy sprawdzić opublikowany plik wsdl w przeglądarce i upewnić się, że zawiera on oczekiwaną strategię bezpieczeństwa (dołączyć? wsdl do punktu końcowego)