欢迎来到入门教程网!

Java

当前位置:主页 > 软件编程 > Java >

基于Java验证jwt token代码实例

来源:本站原创|时间:2020-01-10|栏目:Java|点击:

这篇文章主要介绍了基于Java验证jwt token代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

How to load public certificate from pem file..?地址

1.HS256对称加密

package jwt;
 
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.Vector;
import java.util.Map;
 
import sun.misc.BASE64Decoder;
 
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
 
 
public class JWTValidator {
  private static String JWT_Type = "JWT";
   
  protected boolean validated;
  protected Object[] claims;
   
  public JWTValidator() {
    setValidated(false);
    setClaims(null);
  }
  public String Generate(String secret, String issuer, String audience, String subject){
    try {
      Algorithm algorithm = Algorithm.HMAC256(secret); // HS256
      String token = JWT.create()
        .withIssuer(issuer)
        .withAudience(audience)
        .withSubject(subject)
        .sign(algorithm);
      System.out.println(token);
      return token;
    } catch (Exception exception){
      //UTF-8 encoding not supported
      return "";
    }
  }
   
 
  public void Validate(String token, String secret, String issuer, String audience, String subject) {
    DecodedJWT jwt = null;
    setValidated(false);
     
    if (token == null || secret == null || issuer == null || audience == null || subject == null)
      return;
     
    try {
      jwt = JWT.require(Algorithm.HMAC256(secret.getBytes())).build().verify(token);
    } catch (JWTVerificationException e) {
      return;
    }
     
    if (jwt == null || jwt.getType() == null || !jwt.getType().contentEquals(JWT_Type))
      return;
     
    if (!jwt.getIssuer().contentEquals(issuer) ||
      !jwt.getAudience().contains(audience) ||
      !jwt.getSubject().contentEquals(subject))
      return;
     
    Date now = new Date();
     
    if ((jwt.getNotBefore() != null && jwt.getNotBefore().after(now)) ||
      (jwt.getExpiresAt() != null && jwt.getExpiresAt().before(now)))
      return;
     
    setValidated(true);
 
    Map<String, Claim> claimsMap = jwt.getClaims();
    Vector<Claim> claimsVector = new Vector<Claim>();
     
    if (claimsMap != null) {
      for (Map.Entry<String, Claim> entry : claimsMap.entrySet()) {
        String key = entry.getKey();
        if (key != null && !key.matches("aud|sub|iss|exp|iat")) {         
          //claimsVector.add(new Claim(key, entry.getValue().asString()));
        }
      }   
    }
 
    setClaims(claimsVector.isEmpty() ? null : claimsVector.toArray());
  }
 
  public boolean isValidated() { return validated; }
  public void setValidated(boolean val) { validated = val; }
 
  public Object[] getClaims() { return claims; }
  public void setClaims(Object[] val) { claims = (val == null ? new Object[0] : val); }
}

2.RS256不对称加密,需要用public cert来验证

package jwt;
 
import junit.framework.TestCase;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
 
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.UUID;
 
public class JWTValidatorForRSA extends TestCase{
 
  public void testCreateToken() throws IOException {
    System.out.println(createToken());
  }
 
  public void testVerifyToken() throws Exception {
    String token = createToken();
    System.out.println(token);
     
    String pkeyPath = "D:\\temp\\idsrv4.crt";
    JwtClaims jwtClaims = verifyToken(token,pkeyPath);
    System.out.println(jwtClaims.getClaimValue("name"));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(jwtClaims.getIssuedAt().getValueInMillis()));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(jwtClaims.getExpirationTime().getValueInMillis()));
  }
 
  /**
   * 生成jwt,SHA256加密
   * @return
   * @throws IOException
   */
  public String createToken() throws IOException {
    String privateKeyPath = "D:\\temp\\idsrv4.key";
    PrivateKey privateKey = getPrivateKey(getStringFromFile(privateKeyPath));
    final JwtClaims claims = new JwtClaims();
    claims.setClaim("name", "jack");
    claims.setSubject("a@a.com");
    claims.setAudience("test");//用于验证签名是否合法,验证方必须包含这些内容才验证通过
    claims.setExpirationTimeMinutesInTheFuture(-1); // 60*24*30);
    claims.setIssuedAtToNow();
 
    // Generate the payload
    final JsonWebSignature jws = new JsonWebSignature();
    jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
    jws.setPayload(claims.toJson());
    jws.setKeyIdHeaderValue(UUID.randomUUID().toString());
 
    // Sign using the private key
    jws.setKey(privateKey);
    try {
      return jws.getCompactSerialization();
    } catch (JoseException e) {
      return null;
    }
  }
 
  /**
   * 验证jwt
   * @param token
   * @return
   * @throws Exception
   */
  public JwtClaims verifyToken(String token,String publicKeyPath) throws Exception {
 
    try {
      PublicKey publicKey = getPublicKey(publicKeyPath);
 
      JwtConsumer jwtConsumer = new JwtConsumerBuilder()
          .setRequireExpirationTime()
          .setVerificationKey(publicKey)
          .setExpectedAudience("test")//用于验证签名是否合法,可以设置多个,且可设置必须存在项,如果jwt中不包含这些内容则不通过
          .build();
 
      return jwtConsumer.processToClaims(token);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 
  private String getStringFromFile(String filePath) throws IOException {
    //  生成方法:安装openssl,执行   openssl genrsa -out private.pem 2048
    return IOUtils.toString(new FileInputStream(filePath));
  }
 
  /**
   * 获取PublicKey对象
   * @param publicKeyBase64
   * @return
   * @throws NoSuchAlgorithmException
   * @throws InvalidKeySpecException
   * @throws CertificateException
   * @throws FileNotFoundException
   */
  private PublicKey getPublicKey(String publicKeyPath) throws NoSuchAlgorithmException, InvalidKeySpecException, CertificateException, FileNotFoundException {
    /* Not work : data isn't an object ID (tag = 2)
    String pem = publicKeyBase64
        .replaceAll("\\-*BEGIN.*CERTIFICATE\\-*", "")
        .replaceAll("\\-*END.*CERTIFICATE\\-*", "");
    java.security.Security.addProvider(
        new org.bouncycastle.jce.provider.BouncyCastleProvider()
    );
    System.out.println(pem);
     
    X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(pem));
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
 
    PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
    */
     
    CertificateFactory fact = CertificateFactory.getInstance("X.509");
    FileInputStream is = new FileInputStream (publicKeyPath);
    X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
    PublicKey publicKey = cer.getPublicKey();
     
    System.out.println(publicKey);
     
    return publicKey;
  }
 
  /**
   * 获取PrivateKey对象
   * @param privateKeyBase64
   * @return
   */
  private PrivateKey getPrivateKey(String privateKeyBase64) {
    String privKeyPEM = privateKeyBase64
        .replaceAll("\\-*BEGIN.*KEY\\-*", "")
        .replaceAll("\\-*END.*KEY\\-*", "");
 
    // Base64 decode the data
    byte[] encoded = Base64.decodeBase64(privKeyPEM);
 
    try {
      DerInputStream derReader = new DerInputStream(encoded);
      DerValue[] seq = derReader.getSequence(0);
 
      if (seq.length < 9) {
        throw new GeneralSecurityException("Could not read private key");
      }
 
      // skip version seq[0];
      BigInteger modulus = seq[1].getBigInteger();
      BigInteger publicExp = seq[2].getBigInteger();
      BigInteger privateExp = seq[3].getBigInteger();
      BigInteger primeP = seq[4].getBigInteger();
      BigInteger primeQ = seq[5].getBigInteger();
      BigInteger expP = seq[6].getBigInteger();
      BigInteger expQ = seq[7].getBigInteger();
      BigInteger crtCoeff = seq[8].getBigInteger();
 
      RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp,
          primeP, primeQ, expP, expQ, crtCoeff);
 
      KeyFactory factory = KeyFactory.getInstance("RSA");
      return factory.generatePrivate(keySpec);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

上一篇:java实现液晶数字字体显示当前时间

栏    目:Java

下一篇:Java实现动态数字时钟

本文标题:基于Java验证jwt token代码实例

本文地址:https://www.xiuzhanwang.com/a1/Java/8935.html

网页制作CMS教程网络编程软件编程脚本语言数据库服务器

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:835971066 | 邮箱:835971066#qq.com(#换成@)

Copyright © 2002-2020 脚本教程网 版权所有