springboot-jwt令牌采用秘钥加密
1.使用秘钥库生成工具生成秘钥库文件(JWT令牌 JWT概述和简单使用)
本例中生成的秘钥库名称为: xc.keystore
2.然后根据秘钥库得到公钥,并存储为一个公钥文件,由步骤3使用
3.Java代码根据秘钥库分别获得java对象 publickey 和 privateKey
4.使用java对象publickey 和 privateKey 进行jwt的加解密
token的工具类代码如下:
package com.example.demo.common.utils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import sun.security.rsa.RSAPublicKeyImpl; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.nio.charset.Charset; import java.security.*; import java.security.cert.CertificateException; import java.util.*; public class JwtTokenUtil implements Serializable { private static final long serialVersionUID = 1L; private static final String USERNAME = Claims.SUBJECT; private static final String CREATED = "created"; private static final String AUTHORITIES = "authorities"; private static final String SECRET = "MyJwtSecret"; private static final PublicKey PUBLIC_KEY = getPublicKey(); private static final PrivateKey PRIVATE_KEY = getPrivateKey(); public static final long EXPIRE_TIME_REFRESH = 12 * 60 * 60 * 1000; public static final long EXPIRE_TIME_ACCESS = 60 * 30 * 1000; public static final String KEYSTORE_LOCATION = "keystore/xc.keystore"; public static final String PUBLICKEY_LOCATION = "keystore/public.key"; public static final String KEYSTORE_PASSWORD = "xuechengkeystore"; public static final String KEY_PASSWORD = "xuecheng"; public static final String KEYSTORE_ALIAS = "xckey"; private static PublicKey getPublicKey() { ClassPathResource resource = new ClassPathResource(PUBLICKEY_LOCATION); PublicKey publicKey = null; BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), Charset.forName("utf-8"))); StringBuffer buffer = new StringBuffer(); String line = ""; while ((line = reader.readLine()) != null) { buffer.append(line); } publicKey = RSAPublicKeyImpl.newKey(Base64.getDecoder().decode(buffer.toString())); } catch (IOException | InvalidKeyException e) { e.printStackTrace(); } finally{ if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return publicKey; } private static PrivateKey getPrivateKey() { PrivateKey privateKey = null; try { ClassPathResource resource = new ClassPathResource(KEYSTORE_LOCATION); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(resource.getInputStream(), KEYSTORE_PASSWORD.toCharArray()); privateKey = (PrivateKey) ks.getKey(KEYSTORE_ALIAS, KEY_PASSWORD.toCharArray()); } catch (IOException | CertificateException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException e) { e.printStackTrace(); } return privateKey; } @Test public void test01() { HashMap<String, Object> tokenMap = new HashMap<>(); tokenMap.put("id", "123"); tokenMap.put("name", "guohao"); tokenMap.put("roles", "r01,r02"); tokenMap.put("ext", "1"); String token = Jwts.builder().signWith(SignatureAlgorithm.RS256, PRIVATE_KEY).setClaims(tokenMap).setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000)).compact(); System.out.println(token); // PublicKey publicKey = RSAPublicKeyImpl.newKey(Base64.getDecoder().decode(PUBLIC_KEY)); Claims body = Jwts.parser().setSigningKey(PUBLIC_KEY).parseClaimsJws(token).getBody(); System.out.println(body); } /** * 生成refreshToken令牌 * * @param * @return 令牌 */ public static String generateToken(Authentication authentication, long expiredTimeOffset) { Map<String, Object> claims = new HashMap<>(3); claims.put(USERNAME, SecurityUtil.getUsername(authentication)); claims.put(CREATED, new Date()); claims.put(AUTHORITIES, authentication.getAuthorities()); return generateToken(claims, expiredTimeOffset); } /** * 从数据声明生成令牌 * * @param claims 数据声明 * @return 令牌 */ public static String generateToken(Map<String, Object> claims, long expiredTimeOffset) { Date expirationDate = new Date(System.currentTimeMillis() + expiredTimeOffset); return Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.RS256, PRIVATE_KEY).compact(); } /** * 从令牌中获取用户名 * * @param token 令牌 * @return 用户名 */ public static String getUsernameFromToken(String token) { String username; try { Claims claims = getClaimsFromToken(token); username = claims.getSubject(); } catch (Exception e) { username = null; } return username; } /** * 根据请求令牌获取登录认证信息 * * @param * @return 用户名 */ public static Authentication getAuthenticationeFromToken(HttpServletRequest request) { Authentication authentication = null; // 获取请求携带的令牌 String token = JwtTokenUtil.getToken(request); if (token != null) { // 请求令牌不能为空 if (SecurityUtil.getAuthentication() == null) { // 上下文中Authentication为空 Claims claims = getClaimsFromToken(token); if (claims == null) { return null; } String username = claims.getSubject(); if (username == null) { return null; } if (isTokenExpired(token)) { return null; } Object authors = claims.get(AUTHORITIES); List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); if (authors != null && authors instanceof List) { for (Object object : (List) authors) { authorities.add(new SimpleGrantedAuthority((String) ((Map) object).get("authority"))); } } authentication = new UsernamePasswordAuthenticationToken(username, null, authorities); } else { if (validateToken(token, SecurityUtil.getUsername())) { // 如果上下文中Authentication非空,且请求令牌合法,直接返回当前登录认证信息 authentication = SecurityUtil.getAuthentication(); } } } return authentication; } /** * 从令牌中获取数据声明 * * @param token 令牌 * @return 数据声明 */ private static Claims getClaimsFromToken(String token) { return Jwts.parser().setSigningKey(PUBLIC_KEY).parseClaimsJws(token).getBody(); } /** * 验证令牌 * * @param token * @param username * @return */ public static Boolean validateToken(String token, String username) { String userName = getUsernameFromToken(token); return (userName.equals(username) && !isTokenExpired(token)); } /** * 刷新令牌 * * @param token * @return */ public static String refreshToken(String token) { String refreshedToken; try { Claims claims = getClaimsFromToken(token); claims.put(CREATED, new Date()); refreshedToken = generateToken(claims, EXPIRE_TIME_REFRESH); } catch (Exception e) { refreshedToken = null; } return refreshedToken; } /** * 判断令牌是否过期 * * @param token 令牌 * @return 是否过期 */ public static Boolean isTokenExpired(String token) { try { Claims claims = getClaimsFromToken(token); Date expiration = claims.getExpiration(); return expiration.before(new Date()); } catch (Exception e) { return false; } } /** * 获取请求token * * @param request * @return */ public static String getToken(HttpServletRequest request) { String token = request.getHeader("Authorization"); String tokenHead = "Bearer "; if (token == null) { token = request.getHeader("token"); } else if (token.contains(tokenHead)) { token = token.substring(tokenHead.length()); } if ("".equals(token)) { token = null; } return token; } }
使用相关依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency>

浙公网安备 33010602011771号