Signe de JAX-WS SOAP demande
Je voudrais écrire un JAX-WS service web qui signe mes messages SOAP à l'aide de la http://www.w3.org/TR/xmldsig-core/ recommandation.
Avec ce que j'ai trouvé sur internet, j'ai écrit un JAX-WS gestionnaire (SOAPHandler<SOAPMessageContext>
) qui parvient à changer une copie de la requête SOAP:
@Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage message = smc.getMessage();
if (outboundProperty) {
try {
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
Source source = soapPart.getContent();
Node root = null;
Document doc22 = null;
if (source instanceof DOMSource) {
root = ((DOMSource) source).getNode();
} else if (source instanceof SAXSource) {
InputSource inSource = ((SAXSource) source).getInputSource();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
doc22 = db.parse(inSource);
root = (Node) doc22.getDocumentElement();
}
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
//Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("client_keystore.jks"), "changeit".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) ks.getEntry("client", new KeyStore.PasswordProtection("changeit".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
//Create the KeyInfo containing the X509Data.
KeyInfoFactory kif2 = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif2.newX509Data(x509Content);
KeyInfo ki = kif2.newKeyInfo(Collections.singletonList(xd));
Element header = getFirstChildElement(root/*.getDocumentElement()*/);
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), header /*doc.getDocumentElement()*/);
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
//TODO: change this to update the SOAP message, not write it to disks
OutputStream os = new FileOutputStream("out.xml");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(root), new StreamResult(os));
} catch (Exception ex) {
System.out.println(ex);
}
}
return true;
}
Mais je ne peux pas comprendre comment mettre à jour la requête SOAP?
- Ne soapPart.setContent(nouveau DOMSource(racine)) ne fonctionne pas? Je suis juste deviner, je ne l'ai pas fait moi-même.
- Malheureusement, cela vide la bode et éléments d'en-tête. Merci pour la recherche, si!
- Avez-vous trouvé une solution à ce problème encore? Je suis curieux, je vais faire quelque chose de similaire
- J'ai abandonné l'idée, mais je suis toujours intéressé à une solution si quelqu'un a un!
- Mon test me dit que vous n'avez pas à faire quoi que ce soit, depuis la signature déjà des mises à jour du message SOAP.
Vous devez vous connecter pour publier un commentaire.
La façon la plus simple est d'utiliser la fonctionnalité intégrée dans l'application server. Par exemple :La sécurisation de JAX-WS services Web à l'aide de la sécurité de niveau message avec WebSphere Application Server
Comment configurer la signature a ÉTÉ vous pouvez trouver ici.
Et voici WebLogic de la documentation sur la Configuration de la Sécurité de Niveau Message.
Je développe un SOAPHandler pour Xml Digital Signature de la Requête Soap.
Je pense que le problème dans le code de @AndrewBourgeois est la façon d'obtenir la Source.
Ce qui concerne,
Vous pouvez essayer soapPart.saveChanges();
Après la ligne de code:
insérer cette déclaration:
Il va enregistrer vos modifications.