如何使用通用模块Gatling3.1生成HMAC签名

时间:2019-07-28 06:06:21

标签: scala gatling

我正在为HMAC身份验证授权的微服务制作测试脚本。该脚本由gatling-3.1编写 我面临一个问题,生成HMAC签名的过程是多余的。

我在Github中引用了示例代码,如下所示: https://github.com/gatling/gatling/blob/ace52b37bc60e5ebc168385694a283c4851cb3f9/gatling-http/src/test/scala/io/gatling/http/compile/HttpCompileTest.scala#L229-L245

我编写了代码,并确认已在每个请求中将计算出的签名添加到Authorization标头中。 但是我不知道如何按模块生成签名,因此,我的代码仍然是多余的。

请注意(1)和(2)。

POST

我想使用可维护性模块来计算request_1和request_2的签名。 如果您知道,请告诉我。

解决方案: 谢谢乔治。我可以删除冗余代码,如下所示。

package computerdatabase

class BasicSimulation extends Simulation {

  val httpProtocol = http
    .baseUrl("http://computer-database.gatling.io") // Here is the root for all relative URLs

  val scn = scenario("Scenario Name") // A scenario is a chain of requests and pauses
    .exec(http("request_1")
    .get("/")
    //---------- (1) Calculate signature in "request_1" by customized logic ----------
    .sign(new SignatureCalculator {                   
      override def sign(request: Request): Unit = {
        import java.util.Base64
        import javax.crypto.Mac
        import javax.crypto.spec.SecretKeySpec
        val mac = Mac.getInstance("HmacSHA256")
        mac.init(new SecretKeySpec("THE_SECRET_KEY".getBytes("UTF-8"), "HmacSHA256"))
        val rawSignature = mac.doFinal("".getBytes("UTF-8"))
        val authorization = Base64.getEncoder.encodeToString(rawSignature)
        request.getHeaders.add("Authorization", authorization)
      }
    })
    //---------- (1) End ----------
    )
    .pause(7) // Note that Gatling has recorded real time pauses
    .exec(http("request_2")
    .get("/computers?f=macbook")
    //---------- (2) Calculate signature in "request_2". Same logic as (1)...It is redundant----------
    .sign(new SignatureCalculator {
      override def sign(request: Request): Unit = {
        import java.util.Base64
        import javax.crypto.Mac
        import javax.crypto.spec.SecretKeySpec
        val mac = Mac.getInstance("HmacSHA256")
        mac.init(new SecretKeySpec("THE_SECRET_KEY".getBytes("UTF-8"), "HmacSHA256"))
        val rawSignature = mac.doFinal("".getBytes("UTF-8"))
        val authorization = Base64.getEncoder.encodeToString(rawSignature)
        request.getHeaders.add("Authorization", authorization)
      }
    })
    //---------- (2) End ----------
    )
  setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))
}

1 个答案:

答案 0 :(得分:0)

只需使用变量来保存您的SignatureCalculator

val signatureCalculator = new SignatureCalculator {
  // ...

或使用lambda syntax

val signatureCalculator: SignatureCalculator = { request =>

那你就可以做

.exec(http("request_2")
  .get("/computers?f=macbook")
  .sign(signatureCalculator)
)

如果虚拟用户的密钥不同,则必须将其设置为Expression。要依赖会话属性,您可以编写如下内容:

val signatureCalculator: Expression[SignatureCalculator] = { session =>
  session("secretKey")
    .validate[String]
    .map { secretKey =>
      { request =>
        // ...
      }
    }
}