【问题标题】:Verify Access token signature using java-jwt使用 java-jwt 验证访问令牌签名
【发布时间】:2021-11-16 02:35:43
【问题描述】:

我正在尝试验证由 KeyCloak 授权服务器生成的 JWT 访问令牌。

我已经从 http://ip-address:port/auth/realms/

为了验证访问令牌,我使用https://mvnrepository.com/artifact/com.auth0/java-jwt

并参考https://www.baeldung.com/java-jwt-token-decode 验证签名。

我正在尝试的代码:

 String publicKey =<public_key from http://<ip>:<port>/auth/realms/<app> >
 
 String accessToken =<valid access token from keycloak>
  
 String[] chunks = accessToken.split("\\.");
 
 Base64.Decoder decoder = Base64.getDecoder();
 String header = new String(decoder.decode(chunks[0]));  // {"alg":"RS256","typ" : "JWT","kid" : "dsssdssdf"}
 String payload = new String(decoder.decode(chunks[1])); //{"exp":1632237161,"iat":1632236861,"auth_time":1632236854,"jt..."}
 String signature = chunks[2]; // <signature from access token>
 
 SignatureAlgorithm sa = SignatureAlgorithm.RS256;
 String tokenWithoutSignature = chunks[0] + "." + chunks[1];
 SecretKeySpec secretKeySpec = new SecretKeySpec(publicKey.getBytes(), sa.getJcaName());
 
 DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
 
 if (!validator.isValid(tokenWithoutSignature, signature)) {
      System.out.println("=============== Invalid access token");
    } else {
      System.out.println("============= valid access token");
    }

运行上述代码后观察到以下错误:

java.lang.IllegalArgumentException: RSA Signature validation requires either a RSAPublicKey or RSAPrivateKey instance.
    at io.jsonwebtoken.lang.Assert.isTrue(Assert.java:38)
    at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.<init>(RsaSignatureValidator.java:36)
    at io.jsonwebtoken.impl.crypto.DefaultSignatureValidatorFactory.createSignatureValidator(DefaultSignatureValidatorFactory.java:43)
    at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.<init>(DefaultJwtSignatureValidator.java:37)
    at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.<init>(DefaultJwtSignatureValidator.java:32)
    

有人可以帮忙吗?

【问题讨论】:

    标签: java oauth jjwt


    【解决方案1】:

    我尝试类似:

    String publicKey =<public_key from http://<ip>:<port>/auth/realms/<app> >
    byte[] decoded = Base64.getDecoder().decode(publicKey);
    
    String algorithm = "RSA";
    KeyFactory kf = KeyFactory.getInstance(algorithm);
    PublicKey generatedPublic = kf.generatePublic(new X509EncodedKeySpec(decoded));
    
    String accessToken =<valid access token from keycloak> 
    String[] chunks = accessToken.split("\\.");
    
    Base64.Decoder decoder = Base64.getDecoder();
    
    String header = new String(decoder.decode(chunks[0]));  // {"alg":"RS256","typ" : "JWT","kid" : "dsssdssdf"}
    String payload = new String(decoder.decode(chunks[1])); //{"exp":1632237161,"iat":1632236861,"auth_time":1632236854,"jt..."}
    String signature = chunks[2]; // <signature from access token>
    
    SignatureAlgorithm sa = SignatureAlgorithm.RS256;
    String tokenWithoutSignature = chunks[0] + "." + chunks[1];
    
    DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, generatedPublic);
    
    if (!validator.isValid(tokenWithoutSignature, signature)) {
               System.out.println("=============== Invalid access token");
    } else {
              System.out.println("============= valid access token");
    }
    

    而且成功了!!

    【讨论】:

      猜你喜欢
      • 2019-11-01
      • 2021-08-24
      • 2018-05-29
      • 2018-11-25
      • 2020-10-27
      • 2018-09-16
      • 2022-10-15
      • 2019-06-14
      • 2018-09-30
      相关资源
      最近更新 更多