ultima peticion example soap jmeter signature

peticion - soap xml rpc request jmeter



Agregar firma en una solicitud SOAP en Apache JMeter (2)

Es necesario realizar algunas secuencias de comandos para encriptar el mensaje a través del PreProcesador JSR223 . La idea es obtener el cuerpo de la muestra actual, encriptarlo y reemplazarlo sobre la marcha.

  1. Agregue el preprocesador JSR223 como un elemento secundario de la solicitud
  2. Use el siguiente código como referencia:

    import com.sun.org.apache.xml.internal.security.Init; import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; import com.sun.org.apache.xml.internal.security.signature.XMLSignature; import com.sun.org.apache.xml.internal.security.transforms.Transforms; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.apache.jmeter.protocol.http.sampler.SoapSampler; import org.apache.commons.io.FileUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.Date; //write sampler body into "signature.xml" file String body = sampler.getXmlData(); FileUtils.writeStringToFile(new File("signature.xml"),body); //X509 properties String keystoreType = "JKS"; String keystoreFile = "wso2carbon.jks"; String keystorePass = "wso2carbon"; String privateKeyAlias = "wso2carbon"; String privateKeyPass = "wso2carbon"; String certificateAlias = "wso2carbon"; Element element = null; String BaseURI = signatureFile.toURI().toURL().toString(); //SOAP envelope to be signed //get the private key used to sign, from the keystore KeyStore ks = KeyStore.getInstance(keystoreType); FileInputStream fis = new FileInputStream(keystoreFile); ks.load(fis, keystorePass.toCharArray()); PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray()); //create basic structure of signature javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); String request = sampler.getXmlData(); ByteArrayInputStream in = new ByteArrayInputStream(request.getBytes()); Document doc = dBuilder.parse(in); in.close(); Init.init(); XMLSignature sig = new XMLSignature(doc, BaseURI, XMLSignature.ALGO_ID_SIGNATURE_RSA); element = doc.getDocumentElement(); element.normalize(); element.getElementsByTagName("soapenv:Header").item(0).appendChild(sig.getElement()); { Transforms transforms = new Transforms(doc); transforms.addTransform(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); //Sign the content of SOAP Envelope sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1); } //Signing procedure { X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias); sig.addKeyInfo(cert); sig.addKeyInfo(cert.getPublicKey()); sig.sign(privateKey); } //write signature to file FileOutputStream f = new FileOutputStream(signatureFile); XMLUtils.outputDOMc14nWithComments(doc, f); f.close(); //set sampler''s XML data from file String request = FileUtils.readFileToString(signatureFile); sampler.setXmlData(request);

    Deberá reemplazar los bits relacionados con el almacén de claves y el cifrado según su configuración y definición de servicio.

Consulte Eliminar el dolor de Load Testing Secure Web Services para obtener una explicación completa

Necesito agregar firma usando el certificado X509 en la solicitud SOAP en Apache JMeter. Ya tengo .p12 conmigo. Ayuda por favor cómo puedo lograrlo en Apache JMeter. Sé cómo hacerlo en SOAPUI pero no encuentro ningún camino en JMeter.


No sé si todavía necesita esta respuesta, pero me encontré con el mismo problema y lo solucioné después de un par de días de trabajo y supongo que a otros también les puede resultar útil ...

Basé mi respuesta en la respuesta de Dmitri T; la publicación del blog en el contador de incendios , este informe de errores + algunos piratería personalizada.

Supongamos que necesita firmar esta solicitud:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://custom.namespace.com/service-v1.0-rc2"> <soap:Header> <wsa:MessageID xmlns:wsa="http://www.w3.org/2004/12/addressing">a2749a0f-555-9135-367ed901d244</wsa:MessageID> </soap:Header> <soap:Body> <ser:request> <ser:person> <ser:id>11552</ser:id> <ser:number>81067776992</ser:number> </ser:person> </ser:request> </soap:Body> </soap:Envelope>

Has seguido la guía del medidor de blaze hasta la parte con el código personalizado de java para firmar la solicitud.

En lugar de usar ese código, haga lo siguiente:

Copie y pegue el siguiente código en JMeter (3.0):

import com.example.wss.SOAPSecurity; import org.apache.jmeter.services.FileServer; // get SOAP message from parent sampler body String soapData = sampler.getArguments().getArgument(0).getValue(); String baseDir = FileServer.getFileServer().getBaseDir(); String pathToKeystore = baseDir + File.separator + "keystore_files" + File.separator + "your.jks"; String keystorePassword = "yourPassword"; int timeToLive = 5000; String signingAlias = "yourAlias"; String encryptAlias = "yourEncryptingAlias"; String secureSoap = ""; try { secureSoap = SOAPSecurity.secureSoapMessageFromString(soapData, pathToKeystore, keystorePassword, null, null, timeToLive, signingAlias, yourEncryptingAlias); } catch (Exception ex){ log.warn("Error in script", ex); throw ex; } // replace parent sampler body with secured SOAP message sampler.getArguments().getArgument(0).setValue(secureSoap); vars.put("SoapDataRaw", secureSoap);

Use groovy como intérprete.

Este es el archivo de clase Java adaptado para mi caso de uso:

package com.example.wss; import org.apache.ws.security.WSConstants; import org.apache.ws.security.WSEncryptionPart; import org.apache.ws.security.WSSecurityException; import org.apache.ws.security.components.crypto.Crypto; import org.apache.ws.security.components.crypto.CryptoFactory; import org.apache.ws.security.components.crypto.Merlin; import org.apache.ws.security.message.WSSecEncrypt; import org.apache.ws.security.message.WSSecHeader; import org.apache.ws.security.message.WSSecSignature; import org.apache.ws.security.message.WSSecTimestamp; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.soap.*; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.net.ssl.*; import javax.xml.transform.dom.DOMSource; import java.io.*; import java.security.*; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class SOAPSecurity { private KeyStore keystore; private KeyManagerFactory keyManagerFactory; private String keystorePassword; private TrustManagerFactory trustManagerFactory; private KeyStore truststore; private String truststorePassword; private Crypto crypto; public SOAPSecurity(String pathToKeystore, String keystorePassword, String pathToTruststore, String truststorePassword) throws IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException, WSSecurityException { keystore = KeyStore.getInstance("JKS"); InputStream fileReader = new FileInputStream(new File(pathToKeystore)); keystore.load(fileReader, keystorePassword.toCharArray()); this.keystorePassword = keystorePassword; keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keystore, keystorePassword.toCharArray()); Properties properties = new Properties(); properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"); crypto = CryptoFactory.getInstance(properties); ((Merlin) crypto).setKeyStore(keystore); truststore = KeyStore.getInstance("JKS"); fileReader = new FileInputStream(new File(pathToTruststore)); truststore.load(fileReader, truststorePassword.toCharArray()); this.truststorePassword = truststorePassword; trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); trustManagerFactory.init(truststore); } //EDITOR: added constructor without truststore public SOAPSecurity(String pathToKeystore, String keystorePassword) throws IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException, WSSecurityException { keystore = KeyStore.getInstance("JKS"); InputStream fileReader = new FileInputStream(new File(pathToKeystore)); keystore.load(fileReader, keystorePassword.toCharArray()); this.keystorePassword = keystorePassword; keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keystore, keystorePassword.toCharArray()); Properties properties = new Properties(); properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"); crypto = CryptoFactory.getInstance(properties); ((Merlin) crypto).setKeyStore(keystore); } public static String secureSoapMessageFromFile(String messagePath, String pathToKeystore, String keystorePassword, String pathToTruststore, String trustStorePassword, int timeToLive, String signingAlias, String encryptAlias) throws SAXException, ParserConfigurationException, SOAPException, IOException, WSSecurityException, TransformerException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SOAPSecurity soapSecurity = new SOAPSecurity(pathToKeystore, keystorePassword, pathToTruststore, trustStorePassword); SOAPMessage soapMessage = SOAPSecurity.createSOAPRequestFromFile(messagePath); return soapSecurity.applyWSSecurity(soapMessage, timeToLive, signingAlias, encryptAlias); } public static String secureSoapMessageFromString(String messageString, String pathToKeystore, String keystorePassword, String pathToTruststore, String trustStorePassword, int timeToLive, String signingAlias, String encryptAlias) throws SAXException, ParserConfigurationException, SOAPException, IOException, WSSecurityException, TransformerException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SOAPSecurity soapSecurity = new SOAPSecurity(pathToKeystore, keystorePassword); SOAPMessage soapMessage = SOAPSecurity.createSOAPRequestFromString(messageString); return soapSecurity.applyWSSecurity(soapMessage, timeToLive, signingAlias, encryptAlias); } //EDITOR: ...and static signing methods as well public static String secureSoapMessageFromString(String messageString, String pathToKeystore, String keystorePassword, int timeToLive, String signingAlias, String encryptAlias) throws SAXException, ParserConfigurationException, SOAPException, IOException, WSSecurityException, TransformerException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SOAPSecurity soapSecurity = new SOAPSecurity(pathToKeystore, keystorePassword); SOAPMessage soapMessage = SOAPSecurity.createSOAPRequestFromString(messageString); return soapSecurity.applyWSSecurity(soapMessage, timeToLive, signingAlias, encryptAlias); } public static String secureSoapMessageFromFile(String messagePath, String pathToKeystore, String keystorePassword, int timeToLive, String signingAlias, String encryptAlias) throws SAXException, ParserConfigurationException, SOAPException, IOException, WSSecurityException, TransformerException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SOAPSecurity soapSecurity = new SOAPSecurity(pathToKeystore, keystorePassword); SOAPMessage soapMessage = SOAPSecurity.createSOAPRequestFromFile(messagePath); return soapSecurity.applyWSSecurity(soapMessage, timeToLive, signingAlias, encryptAlias); } public interface SOAPDocWriter { Document writeDocument(String s, DocumentBuilder documentBuilder) throws IOException, SAXException; } public static SOAPMessage createSOAPRequestFromFile(String messagePath) throws SOAPException, IOException, ParserConfigurationException, SAXException { SOAPDocWriter pathWriter = (s, d) -> { File messageFile = new File(s); return d.parse(new InputSource(new FileInputStream(messageFile))); }; return createSOAPRequestLambda(messagePath, pathWriter); } public static SOAPMessage createSOAPRequestFromString(String messageString) throws SOAPException, IOException, ParserConfigurationException, SAXException { SOAPDocWriter stringWriter = (s, d) -> d.parse(new InputSource(new StringReader(s))); return createSOAPRequestLambda(messageString, stringWriter); } private static SOAPMessage createSOAPRequestLambda(String s, SOAPDocWriter w) throws SOAPException, IOException, ParserConfigurationException, SAXException { //MessageFactory messageFactory = MessageFactory.newInstance(); //we use the SOAP 1.2 specification MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL); SOAPMessage soapMessage = messageFactory.createMessage(); SOAPPart soapPart = soapMessage.getSOAPPart(); SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); SOAPBody soapBody = soapEnvelope.getBody(); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = w.writeDocument(s, documentBuilder); soapBody.addDocument(document); soapMessage.saveChanges(); return soapMessage; } public static Document toDocument(SOAPMessage soapMsg) throws TransformerConfigurationException, TransformerException, SOAPException, IOException { Source src = soapMsg.getSOAPPart().getContent(); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMResult result = new DOMResult(); transformer.transform(src, result); return (Document) result.getNode(); } /** * Secures a soap message according to the given security actions * * @param soapMessage the soap message to be secured * @param timestampTimeToLive optional: the time to live for the timestamp * @param signatureKeyAlias optional: the alias for the signature key in the keystore * @param encryptionKeyAlias optional: the alias for the encryption key in the keystore * @throws WSSecurityException * @throws IOException * @throws SOAPException * @throws TransformerException */ public String applyWSSecurity(SOAPMessage soapMessage, int timestampTimeToLive, String signatureKeyAlias, String encryptionKeyAlias) throws WSSecurityException, IOException, SOAPException, TransformerException { Document soapMessageDocument = toDocument(soapMessage); // add security header WSSecHeader securityHeader = new WSSecHeader(); securityHeader.setMustUnderstand(false); //we keep the security header element because we need it afterwards Element secHead = securityHeader.insertSecurityHeader(soapMessageDocument); /* for a reason not yet clear to me this method of signing creates a soap request inside a soap request I don''t know why but I know how to work around it: */ //append the security header to the soap:Header parent soapMessageDocument.getElementsByTagName("soap:Header").item(0).appendChild(secHead); //move the soap:Envelope inner soap message to the root of the document and omit the env:Envelope tree soapMessageDocument.replaceChild(soapMessageDocument.getElementsByTagName("soap:Envelope").item(0), soapMessageDocument.getElementsByTagName("env:Envelope").item(0)); //for debugging purposes -> this output shows up in the console output of JMeter.bat //System.out.println("insert:"+soapMessageDocument.getFirstChild().getNodeName()+",soap:"+soapMessageDocument.getElementsByTagName("soap:Envelope").item(0).getNodeName()); WSSecTimestamp timestamp = null; // timestamp document timestamp = new WSSecTimestamp(); timestamp.setTimeToLive(timestampTimeToLive); timestamp.build(soapMessageDocument, securityHeader); // sign document /* EDITOR: originals are commented out and replaced by own values values should be adapted from SOAPUI and searched for at: https://ws.apache.org/wss4j/apidocs/org/apache/wss4j/dom/WSConstants.html */ WSSecSignature signatureBuilder = new WSSecSignature(); signatureBuilder.setUserInfo(signatureKeyAlias, keystorePassword); signatureBuilder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); //signatureBuilder.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); signatureBuilder.setSignatureAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); signatureBuilder.setSigCanonicalization(WSConstants.C14N_EXCL_OMIT_COMMENTS); /* also setDigestAlgo can be set https://ws.apache.org/wss4j/apidocs/org/apache/wss4j/dom/message/WSSecSignature.html#setDigestAlgo-java.lang.String- but I used the default so I didn''t bother */ //also custom signatureBuilder.setUseSingleCertificate(true); List<WSEncryptionPart> signatureParts = new ArrayList<WSEncryptionPart>(); //WSEncryptionPart timestampPart = new WSEncryptionPart(timestamp.getId()); WSEncryptionPart timestampPart = new WSEncryptionPart("Timestamp","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd","Content"); signatureParts.add(timestampPart); //WSEncryptionPart bodyPart = new WSEncryptionPart(WSConstants.ELEM_BODY, WSConstants.URI_SOAP11_ENV, "Element"); WSEncryptionPart bodyPart = new WSEncryptionPart("Body","http://www.w3.org/2003/05/soap-envelope", "Content"); signatureParts.add(bodyPart); signatureBuilder.setParts(signatureParts); signatureBuilder.build(soapMessageDocument, crypto, securityHeader); // encrypt document /* we didn''t encrypt so no need for this code (encryption code untested (by me)) WSSecEncrypt encrypt = new WSSecEncrypt(); encrypt.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); encrypt.setSymmetricEncAlgorithm(WSConstants.AES_128_GCM); encrypt.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOEP); encrypt.setUserInfo(encryptionKeyAlias, keystorePassword); List<WSEncryptionPart> encryptionParts = new ArrayList<WSEncryptionPart>(); WSEncryptionPart encryptionSignaturePart = new WSEncryptionPart("Signature", WSConstants.SIG_NS, "Element"); WSEncryptionPart encryptionBodyPart = new WSEncryptionPart("Body", WSConstants.URI_SOAP11_ENV, "Content"); encryptionParts.add(encryptionBodyPart); encryptionParts.add(encryptionSignaturePart); encrypt.setParts(encryptionParts); encrypt.build(soapMessageDocument, crypto, securityHeader); */ DOMSource domSource = new DOMSource(soapMessageDocument); soapMessage.getSOAPPart().setContent(domSource); soapMessage.saveChanges(); ByteArrayOutputStream out = new ByteArrayOutputStream(); soapMessage.writeTo(out); String strMsg = new String(out.toByteArray()); return strMsg; } }

Coloque el código en un archivo com / example / wss / SOAPSecurity.java

Coloque wss4j-1.6.18.jar en el mismo directorio. http://archive.apache.org/dist/ws/wss4j/1.6.18/

Lo compilé / compilé / implementé con este script .sh (puede usar cygwin para eso):

/cygdrive/c/Program/ Files/ /(x86/)/Java/jdk1.8.0_73/bin/javac.exe -cp wss4j-1.6.18.jar com/example/wss/SOAPSecurity.java cp SOAPSecurity.jar SOAPSecurity.jar.bak$1 zip -r test.zip com/ mv test.zip SOAPSecurity.jar cp SOAPSecurity.jar /cygdrive/c/Program/ Files/ /(x86/)/apache-jmeter-3.0/lib/

Ejecute JMeter 3.0 con el archivo .bat

-> SOAPSecurity.jar debe estar en la carpeta apache-jmeter-3.0 / lib /

-> También tengo esta configuración en el archivo system.properties de JMeter:

-Djavax.net.ssl.keyStore=C:/path/to/client.jks -Djavax.net.ssl.keyStorePassword=verySecret

-> y agregó un elemento de configuración de almacén de claves a la solicitud de jabón en JMeter

Por lo tanto, esto es todo, no dude en darle un giro y dígame si le funcionó, de lo contrario podría brindarle alguna ayuda, si desea depurar usted mismo una manera excelente de hacerlo es adaptando / colocando System.out.println''s en la clase personalizada, brinda información muy útil sobre lo que está sucediendo y puede ser un gran salvavidas,

¡Sigue divirtiéndote!

S.