, , , , ... ...
; blazemeter, this bugreport + .
, :
<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>
blazemeter, java- .
:
JMeter (3.0) :
import com.example.wss.SOAPSecurity;
import org.apache.jmeter.services.FileServer;
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;
}
sampler.getArguments().getArgument(0).setValue(secureSoap);
vars.put("SoapDataRaw", secureSoap);
groovy .
java, :
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);
}
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);
}
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(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();
}
public String applyWSSecurity(SOAPMessage soapMessage,
int timestampTimeToLive,
String signatureKeyAlias,
String encryptionKeyAlias) throws WSSecurityException, IOException, SOAPException, TransformerException {
Document soapMessageDocument = toDocument(soapMessage);
WSSecHeader securityHeader = new WSSecHeader();
securityHeader.setMustUnderstand(false);
Element secHead = securityHeader.insertSecurityHeader(soapMessageDocument);
soapMessageDocument.getElementsByTagName("soap:Header").item(0).appendChild(secHead);
soapMessageDocument.replaceChild(soapMessageDocument.getElementsByTagName("soap:Envelope").item(0),
soapMessageDocument.getElementsByTagName("env:Envelope").item(0));
WSSecTimestamp timestamp = null;
timestamp = new WSSecTimestamp();
timestamp.setTimeToLive(timestampTimeToLive);
timestamp.build(soapMessageDocument, securityHeader);
WSSecSignature signatureBuilder = new WSSecSignature();
signatureBuilder.setUserInfo(signatureKeyAlias, keystorePassword);
signatureBuilder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
signatureBuilder.setSignatureAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1");
signatureBuilder.setSigCanonicalization(WSConstants.C14N_EXCL_OMIT_COMMENTS);
signatureBuilder.setUseSingleCertificate(true);
List<WSEncryptionPart> signatureParts = new ArrayList<WSEncryptionPart>();
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("Body","http://www.w3.org/2003/05/soap-envelope", "Content");
signatureParts.add(bodyPart);
signatureBuilder.setParts(signatureParts);
signatureBuilder.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;
}
}
com\example\wss\SOAPSecurity.java
wss4j-1.6.18.jar .
http://archive.apache.org/dist/ws/wss4j/1.6.18/
// .sh script ( cygwin):
/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/
JMeter 3.0 .bat
- > SOAPSecurity.jar apache-jmeter-3.0/lib/
- > JMeter system.properties:
-Djavax.net.ssl.keyStore=C:/path/to/client.jks
-Djavax.net.ssl.keyStorePassword=verySecret
- > JMeter
, , , , , , / System.out.println , , ,
!!!
S.