|
@@ -0,0 +1,225 @@
|
|
|
+package com.xiaoan.web.shiro;
|
|
|
+
|
|
|
+import com.auth0.jwt.JWT;
|
|
|
+import com.auth0.jwt.exceptions.JWTDecodeException;
|
|
|
+import com.auth0.jwt.interfaces.Claim;
|
|
|
+import com.auth0.jwt.interfaces.DecodedJWT;
|
|
|
+import io.jsonwebtoken.Claims;
|
|
|
+import io.jsonwebtoken.JwtBuilder;
|
|
|
+import io.jsonwebtoken.Jwts;
|
|
|
+import io.jsonwebtoken.SignatureAlgorithm;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+public class JwtUtil2 {
|
|
|
+
|
|
|
+ //生成签名的时候使用的秘钥secret
|
|
|
+ private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK&sdfkjsdrow32234545fdf>?N<:{LWPW";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 用户登录成功后生成Jwt
|
|
|
+ * 使用Hs256算法 私匙使用用户密码
|
|
|
+ *
|
|
|
+ * @param ttlMillis jwt过期时间
|
|
|
+ * @param userName 用户名
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String createJWT(long ttlMillis, String userName) {
|
|
|
+ //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
|
|
|
+ SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
|
|
|
+
|
|
|
+ //生成JWT的时间
|
|
|
+ long nowMillis = System.currentTimeMillis();
|
|
|
+ Date now = new Date(nowMillis);
|
|
|
+
|
|
|
+ //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
|
|
|
+ Map<String, Object> claims = new HashMap<String, Object>();
|
|
|
+ claims.put("userName", userName);
|
|
|
+
|
|
|
+ //下面就是在为payload添加各种标准声明和私有声明了
|
|
|
+ //这里其实就是new一个JwtBuilder,设置jwt的body
|
|
|
+ JwtBuilder builder = Jwts.builder()
|
|
|
+ //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
|
|
|
+ .setClaims(claims)
|
|
|
+ //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
|
|
|
+ .setId(UUID.randomUUID().toString())
|
|
|
+ //iat: jwt的签发时间
|
|
|
+ .setIssuedAt(now)
|
|
|
+ //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
|
|
|
+ .setSubject(userName)
|
|
|
+ //设置签名使用的签名算法和签名使用的秘钥
|
|
|
+ .signWith(signatureAlgorithm, SECRET);
|
|
|
+
|
|
|
+ if (ttlMillis >= 0) {
|
|
|
+ long expMillis = nowMillis + ttlMillis;
|
|
|
+ Date exp = new Date(expMillis);
|
|
|
+ //设置过期时间
|
|
|
+ builder.setExpiration(exp);
|
|
|
+ }/*else{
|
|
|
+ //设置过期时间半小时
|
|
|
+ DateTime expDate = new DateTime().plusMinutes(30);
|
|
|
+ builder.setExpiration(expDate.toDate());
|
|
|
+ }*/
|
|
|
+ return builder.compact();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Token的解密
|
|
|
+ * @param token 加密后的token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static Claims parseJWT(String token) {
|
|
|
+ //得到DefaultJwtParser
|
|
|
+ Claims claims = Jwts.parser()
|
|
|
+ //设置签名的秘钥
|
|
|
+ .setSigningKey(SECRET)
|
|
|
+ //设置需要解析的jwt
|
|
|
+ .parseClaimsJws(token).getBody();
|
|
|
+ return claims;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验token
|
|
|
+ * 在这里可以使用官方的校验,我这里校验的是token中携带的密码于数据库一致的话就校验通过
|
|
|
+ * @param token
|
|
|
+ * @param userName
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static Boolean isVerify(String token, String userName) {
|
|
|
+
|
|
|
+ //得到DefaultJwtParser
|
|
|
+ Claims claims = Jwts.parser()
|
|
|
+ //设置签名的秘钥
|
|
|
+ .setSigningKey(SECRET)
|
|
|
+ //设置需要解析的jwt
|
|
|
+ .parseClaimsJws(token).getBody();
|
|
|
+
|
|
|
+ if (claims.get("userName").equals(userName)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得token中的信息无需secret解密也能获得
|
|
|
+ *
|
|
|
+ * @return token中包含的用户名
|
|
|
+ */
|
|
|
+ public static String getUsername(String token) {
|
|
|
+ try {
|
|
|
+ DecodedJWT jwt = JWT.decode(token);
|
|
|
+ return jwt.getClaim("userName").asString();
|
|
|
+ } catch (JWTDecodeException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static List getUserRole(String token) {
|
|
|
+// try {
|
|
|
+ DecodedJWT jwt = JWT.decode(token);
|
|
|
+ Claim role = jwt.getClaim("role");
|
|
|
+ return role.as(List.class);
|
|
|
+// } catch (JWTDecodeException e) {
|
|
|
+// return null;
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static String createJWT(long ttlMillis, Map<String, Object> paramMap) {
|
|
|
+ //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
|
|
|
+ SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
|
|
|
+
|
|
|
+ String userName = paramMap.get("userName").toString();
|
|
|
+
|
|
|
+ //生成JWT的时间
|
|
|
+ long nowMillis = System.currentTimeMillis();
|
|
|
+ Date now = new Date(nowMillis);
|
|
|
+
|
|
|
+ //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
|
|
|
+ Map<String, Object> claims = new HashMap<String, Object>();
|
|
|
+ claims.put("userName", userName);
|
|
|
+ claims.put("id", paramMap.get("id"));
|
|
|
+ claims.put("role", paramMap.get("role"));
|
|
|
+
|
|
|
+ //下面就是在为payload添加各种标准声明和私有声明了
|
|
|
+ //这里其实就是new一个JwtBuilder,设置jwt的body
|
|
|
+ JwtBuilder builder = Jwts.builder()
|
|
|
+ //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
|
|
|
+ .setClaims(claims)
|
|
|
+ //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
|
|
|
+ .setId(UUID.randomUUID().toString())
|
|
|
+ //iat: jwt的签发时间
|
|
|
+ .setIssuedAt(now)
|
|
|
+ //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
|
|
|
+ .setSubject(userName)
|
|
|
+ //设置签名使用的签名算法和签名使用的秘钥
|
|
|
+ .signWith(signatureAlgorithm, SECRET);
|
|
|
+
|
|
|
+ if (ttlMillis >= 0) {
|
|
|
+ long expMillis = nowMillis + ttlMillis;
|
|
|
+ Date exp = new Date(expMillis);
|
|
|
+ //设置过期时间
|
|
|
+ builder.setExpiration(exp);
|
|
|
+ }/*else{
|
|
|
+ //设置过期时间半小时
|
|
|
+ DateTime expDate = new DateTime().plusMinutes(30);
|
|
|
+ builder.setExpiration(expDate.toDate());
|
|
|
+ }*/
|
|
|
+ return builder.compact();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Long getUserId(String token) {
|
|
|
+ try {
|
|
|
+ DecodedJWT jwt = JWT.decode(token);
|
|
|
+ Claim id = jwt.getClaim("id");
|
|
|
+ return id.asLong();
|
|
|
+ } catch (JWTDecodeException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+// test3();
|
|
|
+// test2();
|
|
|
+ long nowMillis = System.currentTimeMillis();
|
|
|
+ System.out.println(nowMillis);
|
|
|
+ Date exp = new Date(nowMillis);
|
|
|
+ System.out.println(exp);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void test2(){
|
|
|
+ String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOlsiYWRtaW4iLCJyb290Il0sImlkIjoxLCJ1c2VyTmFtZSI6ImFkbWluIiwiaWF0IjoxNTgzODA5MzkzLCJqdGkiOiJkNjZiZTFkYi00MTQ0LTQxMTYtYTNlNi01ZDBjNjhlNTI3ODAifQ.-4AdsVP2RwmPS2grtO4aC8ov9PwkilzaGdThGetBJok";
|
|
|
+ System.out.println(getUserRole(token));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void test3(){
|
|
|
+ HashMap<String, Object> map = new HashMap<>();
|
|
|
+
|
|
|
+ ArrayList<Object> list = new ArrayList<>();
|
|
|
+ list.add("admin");
|
|
|
+ list.add("root");
|
|
|
+
|
|
|
+ map.put("userName", "admin");
|
|
|
+ map.put("id", Long.valueOf("1"));
|
|
|
+ map.put("role", list);
|
|
|
+
|
|
|
+ String token = createJWT(-1, map);
|
|
|
+ System.out.println(token);
|
|
|
+
|
|
|
+ Boolean isVerify = isVerify(token, "admin");
|
|
|
+ System.out.println(isVerify);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void testList(){
|
|
|
+ ArrayList<Object> list = new ArrayList<>();
|
|
|
+ list.add("admin");
|
|
|
+ list.add("root");
|
|
|
+ }
|
|
|
+
|
|
|
+}
|