SOAPFaultException « MustUnderstand têtes (oasis-200401-WSS-secext--WS-Security 1.0.xsd) ne sont pas compris »
-
28-10-2019 - |
Question
J'essaie d'obtenir des informations de service Web qui utilise le type PasswordText WSS. Tout d'abord, je teste à l'aide soapUI et les données obtenu avec succès. Ensuite, je mis en œuvre l'authentification sur Java, l'écriture SecurityHandler:
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;
}
...
}
J'ai vérifié objet doc avec XMLUtils.PrettyDocumentToString(doc)
et a vu, qu'il regarde aime XML envoyé par soupUI - toutes les informations d'authentification (login, mot de passe, nonce et heure de création) étaient sur place, mustUnderstand attribut de tag Security
était vrai.
Alors je faisais face avec l'erreur:
javax.xml.ws.soap.SOAPFaultException: têtes MustUnderstand: [{ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd } sécurité] ne sont pas compris
J'ai trouvé des conseils pour supprimer l'attribut mustUnderstand de l'étiquette de Security
, mais il ne helps. Avez-vous des idées?
P.S.
noeud final de service Web est sur HTTPS .
une partie de la politique de 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>
Demande 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>xxx@example.com</ns:email>
<ns:firstName/>
<ns:lastName/>
</ns:RetrieveCustomerByEmail>
</soapenv:Body>
</soapenv:Envelope>
Ma demande:
<?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>xxx@example.com</ns5:email>
<ns5:firstName/>
<ns5:lastName/>
</ns5:RetrieveCustomerByEmail>
</S:Body>
</S:Envelope>
La solution 2
J'ai trouvé la solution. Dépendances suivantes sont nécessaires:
<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>
Bon article sur ce sujet et quelques pièges de CxF: http://www.logicsector.com/java/how-to-create-a-wsdl-first-soap-client-in-java-with- CxF et-maven /
Autres conseils
Vous pouvez obtenir cette erreur lorsque le service ne gère pas les en-têtes. Le service doit mettre en œuvre un SOAPHandler avec getHeaders () qui résoudrait les en-têtes. Pour le serait que la mise en œuvre correcte suit ci-dessus mentionné défaut
@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;
}
Il est également possible d'obtenir ce lorsque le service est en réalité pas sûr, mais le client tente d'utiliser la configuration de sécurité (éventuellement en utilisant une configuration de sécurité XWSS) Pour cela, il suffit de cocher la wsdl publié à partir d'un navigateur et assurez-vous qu'il contient la politique de sécurité prévu (append? Wsdl à son URL de point final)
Voici ce qui a fonctionné pour moi. En fait, il est une application de l'idée prononcée par @Joseph Rajeev Motha (bien que je l'ai trouvé ailleurs, ici: https://dwuysan.wordpress.com/2012/04/02/jax-ws-wsimport-and- la erreur-mustUnderstand-en-têtes sans compris / #-215 commentaires ), mais sa réponse ne fournit pas boilerplate, et sans elle, la réponse est assez mystérieuse.
S'il vous plaît noter que cette séquence s'applique au cas autonome (où vous publiez un Endpoint
vous).
Étape 1
Créer un SOAPHandler
qui 'comprendre' l'en-tête:
public class WSSESecurityUnderstandPretender implements SOAPHandler<SOAPMessageContext> {
@Override
public Set<QName> getHeaders() {
final QName securityHeader = new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security",
"wsse");
final Set<QName> headers = new HashSet<>();
headers.add(securityHeader);
// notify the runtime that this is handled
return headers;
}
@Override
public boolean handleMessage(SOAPMessageContext context) {
// we must return true, or else the runtime will return
// wrong wrapper element name (like makeTransfer instead of
// makeTransferResponse)
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// we must return true, or else the runtime will return
// wrong wrapper element name (like makeTransfer instead of
// makeTransferResponse)
return true;
}
@Override
public void close(MessageContext context) {
}
}
Étape 2
Créez un fichier handler-chain.xml
et le mettre sur classpath:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains
xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-class>com.mypackage.WSSESecurityUnderstandPretender</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
Étape 3
Annoter votre classe d'implémentation (classe qui est annotées avec @WebService
) avec une référence au fichier de la chaîne de gestionnaire:
@HandlerChain(file = "handler-chain.xml")
Étape 4
Publiez votre point final:
Endpoint endpoint = Endpoint.publish(url, impl);
Une note importante
handleMessage()
et handleFault()
défini par le gestionnaire doit retourner true
. Dans le cas contraire, vous obtiendrez des erreurs étranges comme « élément d'emballage inattendu » parce qu'un nom de l'élément d'emballage différent sera utilisé.