JMe的JSON Web令牌生成器

时间:2015-06-25 09:53:31

标签: java json jmeter jwt beanshell

我试图将API调用返回的JWT值与JMeter中的预期有效值进行比较。为此,我需要在预处理器(BSF预处理器或Bean shell预处理器)中生成预期值,然后将其与从呼叫响应值中提取的值进行比较。 以前有人创造过类似的东西吗? 我目前使用http://jwt.io/手动生成期望值,但是想在JMeter中动态生成这些值。

3 个答案:

答案 0 :(得分:2)

不幸的是,目前还没有用于在JMeter中处理JWT签名请求的现成解决方案。

您似乎至少拥有以下选项:

  1. 尝试使用gatling代替JMeter。 Gatling已经实现了此有效负载的扩展 - gatling-jwt - 但似乎它目前仅支持GET请求。

  2. 您可以尝试使用任何REST Sampler使用JWT签名扩展标准HTTP请求采样器或自定义java implementation of JWT - 就像在OA OAuth Sampler插件中为OAuth有效负载完成一样。 /> 但它可能看起来非常复杂,需要一些开发经验,并且不容易出错 - 不准确的实现可能会导致性能下降并影响您的测试结果。

  3. 在您的问题中提到的用于JWT签名和响应验证的预处理器和后处理器的方法似乎是合理的妥协。
    当我遇到同样的问题时,我的第一个也是非常成功的方法也使用了预处理器和后处理器。
    有几点需要注意:

    • 出于性能原因,使用JSR233(PreProcessorPostProcessor)+ Groovy而不是Beanshell(有关详细信息,请查看this article);
    • list of available中选择JWT的任何稳定的Java实现;
      我已经使用了jjwt并且发现它很好并且使用起来很简单;
    • 在PreProcessor中执行请求体JWT签名,将签名体存储到变量中,将其作为Body Data与HTTP请求一起发送,并在PostProcessor中解码响应;
      HTTP Request // your http call
      Body Data = ${jwtSignedBody} // variable with request body already signed in pre-processor
          JSR233 PreProcessor // sign here your body data and put into variable
          JSR233 PostProcessor // decode JWT-signed response
      
    • 对于调试和进一步处理,在PostProcessor响应体中使用解码后的响应进行更新非常有用,如上面的脚本所示。

答案 1 :(得分:0)

您可以使用 BeanShell PreProcessor 在 HTTP 请求采样器之前计算 JWT 承载令牌。

这是可以生成用于 HTTP 请求的 JWT 不记名令牌的脚本:

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

String jwtIssuer = "your-issuer-here";
String signingKey = "your-signing-key-here";
String subject = "your-subject-here";
// Additional parts of payload here if you like
String groups = "[]";

//The JWT signature algorithm we will be using to sign the token
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

JwtBuilder builder = Jwts.builder()
      .setPayload("{\n" +
              "  \"iss\": \"" + jwtIssuer + "\",\n" +
              "  \"iat\": " + new Date(System.currentTimeMillis()).getTime() / 1000 + ",\n" +
              "  \"sub\": \"" + username + "\",\n" +
              "  \"groups\": " + groups + "\n" +
              "}")
      .setHeaderParam("typ", "JWT")
      .signWith(signatureAlgorithm, signingKey.getBytes());


vars.put("bearerToken", builder.compact());

显然对 subject 进行硬编码并没有太大价值,否则您可以在 http 请求中硬编码不记名令牌。所以你可以使用 vars.get 来获取 jmeter 变量。就我而言,我从“CSV 数据集配置”加载主题,然后设置 String subject = vars.get("subject");

现在您可以在您的 HTTP 请求采样器上创建一个 HTTP 标头管理器来添加不记名令牌:

          <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
            <collectionProp name="HeaderManager.headers">
              <elementProp name="" elementType="Header">
                <stringProp name="Header.name">Authorization</stringProp>
                <stringProp name="Header.value">Bearer ${bearerToken}</stringProp>
              </elementProp>
            </collectionProp>
          </HeaderManager>

运行您的测试,您应该会看到您的不记名令牌存在,并且您的请求已通过身份验证。

JWT bearer token present in request

答案 2 :(得分:0)

JMeter 没有直接的 JWT 处理能力。但是我们可以为此编写一个自定义的 JMeter 扩展。 我们可以将通用 JWT 令牌处理库用于我们的实现。

我为我的测试需求做了一个这样的实现。您可以在 Github 上访问该代码并获得一个想法。 https://github.com/gvasanka/jwt-builder-jmeter-ext