基于Java验证jwt token代码实例

这篇文章主要介绍了基于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;
  }
}

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

(0)

相关推荐

  • Java实现基于token认证的方法示例

    随着互联网的不断发展,技术的迭代也非常之快.我们的用户认证也从刚开始的用户名密码转变到基于cookie的session认证,然而到了今天,这种认证已经不能满足与我们的业务需求了(分布式,微服务).我们采用了另外一种认证方式:基于token的认证. 一.与cookie相比较的优势: 1.支持跨域访问,将token置于请求头中,而cookie是不支持跨域访问的: 2.无状态化,服务端无需存储token,只需要验证token信息是否正确即可,而session需要在服务端存储,一般是通过cookie中的

  • Java中使用JWT生成Token进行接口鉴权实现方法

    先介绍下利用JWT进行鉴权的思路: 1.用户发起登录请求. 2.服务端创建一个加密后的JWT信息,作为Token返回. 3.在后续请求中JWT信息作为请求头,发给服务端. 4.服务端拿到JWT之后进行解密,正确解密表示此次请求合法,验证通过:解密失败说明Token无效或者已过期. 流程图如下: 一.用户发起登录请求 二.服务端创建一个加密后的JWT信息,作为Token返回 1.用户登录之后把生成的Token返回给前端 @Authorization @ResponseBody @GetMappin

  • 基于Java中的StringTokenizer类详解(推荐)

    StringTokenizer是字符串分隔解析类型,属于:Java.util包. 1.StringTokenizer的构造函数 StringTokenizer(String str):构造一个用来解析str的StringTokenizer对象.java默认的分隔符是"空格"."制表符('\t')"."换行符('\n')"."回车符('\r')". StringTokenizer(String str,String delim)

  • Java中基于Shiro,JWT实现微信小程序登录完整例子及实现过程

    小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html : 本文是对接微信小程序自定义登录的一个完整例子实现 ,技术栈为 : SpringBoot+Shiro+JWT+JPA+Redis. 如果对该例子比较感兴趣或者觉得言语表达比较啰嗦,可查看完整的项目地址 : https://github.com/EalenXie/shiro-jwt-applet

  • 深入了解java-jwt生成与校验

    什么是 JWT 这里是jwt 官方地址,想了解更多的可以在这里查看. jwt 全称是JSON Web Token,从全称就可以看出 jwt 多用于认证方面的.这个东西定义了一种简洁的,自包含的,安全的方法用于通信双方以 json 对象的形式传递信息.其中简洁,安全,传递信息和 web 系统非常契合. jwt 实际上就是一个字符串,由以下三个部分构成(通过.分隔): Header 头部 Payload 负载 Signature 签名 因此一个 jwt 字符串都是如下的形式: Header.Payl

  • Java微信公众平台开发(6) 微信开发中的token获取

    (一)token的介绍 引用:access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.access_token的存储至少要保留512个字符空间.access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效! (二)token的获取参考文档 获取的流程我们完全可以参考微信官方文档:http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14

  • java获取微信accessToken的方法

    本文实例为大家分享了java如何获取微信accessToken,供大家参考,具体内容如下 package com.fengdi.lianmeng.task; import com.fengdi.lianmeng.common.CacheHelper; import com.fengdi.lianmeng.util.http.HttpRequest; import com.fengdi.lianmeng.util.tencent.CloudSignHelper; import com.fengdi

  • JAVA StringBuffer类与StringTokenizer类代码解析

     StringBuffer类提供了一个字符串的可变序列,类似于String类,但它对存储的字符序列可以任意修改,使用起来比String类灵活得多.它常用的构造函数为: StringBuffer() 构造一个空StringBuffer对象,初始容量为16个字符. StringBuffer(Stringstr) 构造一个StringBuffer对象,初始内容为字符串str的拷贝. 对于StringBuffer类,除了String类中常用的像长度.字符串截取.字符串检索的方法可以使用之外,还有两个较为

  • 基于Java验证jwt token代码实例

    这篇文章主要介绍了基于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; im

  • 基于java实现DFA算法代码实例

    DFA简介 DFA全称为:Deterministic Finite Automaton,即确定有穷自动机.(自己百度吧) 直接代码: 敏感词实体类 package com.nopsmile.dfa; public class Keywords { private String pid; private String Content; public Keywords() { } public Keywords(String content) { super(); Content = content

  • 基于python使用tibco ems代码实例

    这篇文章主要介绍了基于python使用tibco ems代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 TIBCO Enterprise Message Service 是一个消息服务器产品 完全支持JMS的通讯协议,在运行速度和消息吞吐量上表现非常出色, 对于Windows.Linux.Mac.AIX平台都提供支持 代码如下 #encoding=utf-8 import jpype jvmpath=r"C:\Program Files

  • Spring纯Java配置集成kafka代码实例

    这篇文章主要介绍了Spring纯Java配置集成kafka代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 KafkaConfig.java package com.niugang.config; import java.util.HashMap; import java.util.Map; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache

  • 使用jquery 的ajax 与 Java servlet的交互代码实例

    这篇文章主要介绍了使用jquery 的ajax 与 Java servlet的交互代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 由于是使用jquery的 所以别忘记导入jq 下面是jsp文件 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!

  • Java程序生成Access文件代码实例

    这篇文章主要介绍了Java程序生成Access文件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 package access; import java.io.File; import java.io.IOException; import java.sql.SQLException; import java.sql.Types; import org.junit.Test; import com.healthmarketscience

  • java 读取系统Properties代码实例

    这篇文章主要介绍了java 读取系统Properties代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java读取系统Properties 属性,针对配置较多的属性值,单独打印,实现代码如下: import java.util.*; public class PropertiesTest { public static void main(String[] args) { Properties properties = System.

  • 基于JavaScript伪随机正态分布代码实例

    这篇文章主要介绍了基于JavaScript伪随机正态分布代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在游戏开发中经常遇到随机奖励的情况,一般会采取先生成数组,再一个一个取的方式发随机奖励. 下面是js测试正态分布代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <ti

  • Java递归遍历文件目录代码实例

    这篇文章主要介绍了Java递归遍历文件目录代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在读取文件降序输出单词及其个数的基础上,将txt文件存入文件夹中,开始递归遍历文件目录,之后输出txt文件中的单词及其个数,仍然是降序排列. 代码如下 import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.Map

  • 基于python实现蓝牙通信代码实例

    这篇文章主要介绍了基于python实现蓝牙通信代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 安装和示例 linux下安装 sudo apt-get install python-pip libglib2.0-dev sudo pip install bluepy 官方示例 import btle class MyDelegate(btle.DefaultDelegate): def __init__(self, params): bt

随机推荐