在Gatling中使用WS Security对SOAP消息进行签名是否可行?
Absolutely! You can add WS Security signing to your SOAP messages in Gatling—even though it’s not a built-in feature like SoapUI’s out-of-the-box tooling. Here’s a step-by-step approach to make it work:
1. Add Required Dependencies
Gatling doesn’t include WS Security libraries by default, so you’ll need to add Apache WSS4J (the same library SoapUI uses under the hood) to your project dependencies. If you’re using SBT, update your build.sbt file with:
libraryDependencies += "org.apache.ws.security" % "wss4j" % "2.4.0" // Use a version compatible with your Gatling setup
2. Create a SOAP Signing Utility
Write a Scala utility class to handle the signing logic using WSS4J. This class will take your raw SOAP payload, keystore details, and return the signed SOAP message. Here’s a basic example:
import org.apache.wss4j.dom.WSConstants import org.apache.wss4j.dom.message.{WSSecHeader, WSSecSignature} import org.w3c.dom.Document import javax.xml.parsers.DocumentBuilderFactory import java.io.{ByteArrayInputStream, ByteArrayOutputStream} import javax.xml.transform.{Transformer, TransformerFactory} import javax.xml.transform.dom.DOMSource import javax.xml.transform.stream.StreamResult object SoapSigner { def signSoapMessage( rawSoap: String, keystorePath: String, keystorePassword: String, keyAlias: String, keyPassword: String ): String = { // Parse raw SOAP into a DOM Document val dbf = DocumentBuilderFactory.newInstance() dbf.setNamespaceAware(true) val doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(rawSoap.getBytes("UTF-8"))) // Initialize the WS Security header val secHeader = new WSSecHeader(doc) secHeader.insertSecurityHeader() // Configure signature settings (match your SoapUI config) val signature = new WSSecSignature(secHeader) signature.setUserInfo(keyAlias, keyPassword) signature.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE) signature.setKeystore(java.security.KeyStore.getInstance(new java.io.File(keystorePath), keystorePassword.toCharArray())) // Perform the signing val signedDoc = signature.build() // Convert the signed DOM back to a string val baos = new ByteArrayOutputStream() val transformer: Transformer = TransformerFactory.newInstance().newTransformer() transformer.transform(new DOMSource(signedDoc), new StreamResult(baos)) baos.toString("UTF-8") } }
3. Integrate the Signer into Your Gatling Scenario
In your Gatling simulation, call the signing utility to process your SOAP payload before sending the request. Here’s how to wire it up:
import io.gatling.core.Predef._ import io.gatling.http.Predef._ class SecureSoapSimulation extends Simulation { val httpProtocol = http .baseUrl("https://your-target-soap-endpoint.com") .acceptHeader("text/xml") .contentTypeHeader("text/xml;charset=UTF-8") val scn = scenario("Signed SOAP Request Test") .exec( http("Send Signed SOAP Message") .post("/your-soap-service-path") .body(StringBody(session => { // Your raw, unsigned SOAP payload val rawSoap = """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://your-service-namespace.com"> | <soapenv:Header/> | <soapenv:Body> | <ser:YourRequest> | <!-- Your request content here --> | </ser:YourRequest> | </soapenv:Body> |</soapenv:Envelope>""".stripMargin // Sign the payload using your utility SoapSigner.signSoapMessage( rawSoap, "src/test/resources/your-keystore.jks", // Path to your keystore "keystore-password", "key-alias", "key-password" ) })) ) setUp(scn.inject(atOnceUsers(1))) .protocols(httpProtocol) }
Key Notes to Keep in Mind
- Match SoapUI’s Settings: Ensure your WSS4J configuration (like key identifier type, signature algorithm) matches what you used in SoapUI—this guarantees the signature works with your target service.
- Namespace Awareness: The utility enables namespace-aware XML parsing, which is critical for valid SOAP messages and proper signing.
- Secure Secrets: Store keystore passwords and paths in Gatling’s configuration files (like
gatling.conf) instead of hardcoding them in your simulation. - Dependency Compatibility: Double-check that your WSS4J version works with your Gatling and Scala versions (Gatling 3.x typically uses Scala 2.13, so pick a compatible WSS4J release).
内容的提问来源于stack exchange,提问作者Magnus Jensen

