如何在 Jmeter 中使用 Java 加载 public 键?

How can I load public key with Java in Jmeter?

我正在尝试在 Jmeter 中生成 JWT 令牌。我为 "automate" 编写了一个 java class,其中包含一个生成令牌的方法。在 IntelliJ 中,一切正常,我收到了一个令牌。因此我构建了一个 jar 文件并将其包含在 jmeter 中。我写了以下 beanshell 脚本。

import com.giro.jwttest.App;
System.out.println("BEANSHELL");
App app = new App();
String token = app.generateToken();
System.out.println(token);
log.info("token: " + token);

为清楚起见,这是我的 java 代码:

package com.giro.jwttest;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class App
{
  private String jwtSubject = "testSubj";
  private String jwtIssuer = "Issuer";
  private String jwtAudience = "Audience";
  private String jksPassword = "123test321";

public PublicKey loadPublicKey(String filename)
        throws Exception
{
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    Certificate cert = cf.generateCertificate(new FileInputStream(filename));
    PublicKey retVal = cert.getPublicKey();
    return retVal;
}

public String generateToken() {
    System.out.println("generateToken method invoke");
    try
    {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        long expMillis = nowMillis + 14400000; //set expiration time to now + 4 hours
        Date exp = new Date(expMillis);

        HashSet<String> roles = new HashSet<>();
        roles.add("Role1");
        roles.add("Role2");


        Map<String, Object> claims = new HashMap<>();
        claims.put("claim_value", "123");
        claims.put("avq_roles", roles);
        claims.put("surname", "Testuser");
        claims.put("givenname", "Test");

        KeyStore ks  = KeyStore.getInstance(KeyStore.getDefaultType());
        System.out.println("getting truststore");
        ks.load(new FileInputStream("/Users/giro/Desktop/jwttest/keystore/hanbotest.jks"), jksPassword.toCharArray());
        System.out.println("after");
        Key key = ks.getKey("hanbotest", jksPassword.toCharArray());
        System.out.println("after1");
        PublicKey publicKey = loadPublicKey("/Users/giro/Desktop/jwttest/keystore/hanbotest.cer");
        System.out.println("after2");
        String compactJws = io.jsonwebtoken.Jwts.builder()
                .setClaims(claims)
                .setSubject(jwtSubject)
                .setAudience(jwtAudience)
                .setExpiration(exp)
                .setIssuedAt(now)
                .setIssuer(jwtIssuer)
                .setNotBefore(now)
                .signWith(SignatureAlgorithm.RS512, key)
                .compact();

        System.out.println(compactJws);

        Jws<Claims> x = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(compactJws);
        String id = x.getBody().getId();
        return compactJws;
    }
    catch (Exception ex)
    {
        System.out.println("Exception occurred");
        ex.printStackTrace();
    }
    return null;
}}

根据输出jmeter stops就行了:

String compactJws = io.jsonwebtoken.Jwts.builder()
        .setClaims(claims)
        .setSubject(jwtSubject)
        .setAudience(jwtAudience)
        .setExpiration(exp)
        .setIssuedAt(now)
        .setIssuer(jwtIssuer)
        .setNotBefore(now)
        .signWith(SignatureAlgorithm.RS512, key)
        .compact();

Jmeter 日志中的错误信息是:

2020-05-08 09:07:16,734 ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import com.giro.jwttest.App;    System.out.println("BEANSHE . . . '' : Typed variable declaration : Method Invocation app.generateToken
2020-05-08 09:07:16,734 WARN o.a.j.p.j.s.BeanShellSampler: Exception executing script. org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import com.giro.jwttest.App;    System.out.println("BEANSHE . . . '' : Typed variable declaration : Method Invocation app.generateToken

有人知道哪里出了问题吗?

根据 Gimby 的建议,我在命令行中有 运行 java 应用程序。它给了我一个更清晰的错误信息。

似乎问题出在目标智能 JDK 和 cmd 行默认 Java 的不同版本上。

在 IDE 中,目标 JDK 设置为 8,在 cmd 行中默认为 14。