JWT相关工具类

jar包

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.10.7</version>
</dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.10.7</version><scope>runtime</scope>
</dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.10.7</version><scope>runtime</scope>
</dependency>

载荷对象

/**
* 为了方便后期获取token中的用户信息,将token中载荷部分单独封装成一个对象
*/
@Data
public class Payload<T> {}

JWT工具类

/*** 生成token以及校验token相关方法*/
public class JwtUtils {private static final String JWT_PAYLOAD_USER_KEY = "user";/*** 私钥加密token** @param userInfo   载荷中的数据* @param privateKey 私钥* @param expire     过期时间,单位分钟* @return JWT*/public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) {return Jwts.builder().claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)).setId(createJTI()).setExpiration(DateTime.now().plusMinutes(expire).toDate()).signWith(privateKey, SignatureAlgorithm.RS256).compact();}/*** 私钥加密token** @param userInfo   载荷中的数据* @param privateKey 私钥* @param expire     过期时间,单位秒* @return JWT*/public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) {return Jwts.builder().claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)).setId(createJTI()).setExpiration(DateTime.now().plusSeconds(expire).toDate()).signWith(privateKey, SignatureAlgorithm.RS256).compact();}/*** 公钥解析token** @param token     用户请求中的token* @param publicKey 公钥* @return Jws<Claims>*/private static Jws<Claims> parserToken(String token, PublicKey publicKey) {return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);}private static String createJTI() {return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes()));}/*** 获取token中的用户信息** @param token     用户请求中的令牌* @param publicKey 公钥* @return 用户信息*/public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) {Jws<Claims> claimsJws = parserToken(token, publicKey);Claims body = claimsJws.getBody();Payload<T> claims = new Payload<>();claims.setId(body.getId());claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType));claims.setExpiration(body.getExpiration());return claims;}/*** 获取token中的载荷信息** @param token     用户请求中的令牌* @param publicKey 公钥* @return 用户信息*/public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) {Jws<Claims> claimsJws = parserToken(token, publicKey);Claims body = claimsJws.getBody();Payload<T> claims = new Payload<>();claims.setId(body.getId());claims.setExpiration(body.getExpiration());return claims;}
}

RSA工具类

非对称加密工具列

public class RsaUtils {private static final int DEFAULT_KEY_SIZE = 2048;/*** 从文件中读取公钥** @param filename 公钥保存路径,相对于classpath* @return 公钥对象* @throws Exception*/public static PublicKey getPublicKey(String filename) throws Exception {byte[] bytes = readFile(filename);return getPublicKey(bytes);}/*** 从文件中读取密钥** @param filename 私钥保存路径,相对于classpath* @return 私钥对象* @throws Exception*/public static PrivateKey getPrivateKey(String filename) throws Exception {byte[] bytes = readFile(filename);return getPrivateKey(bytes);}/*** 获取公钥** @param bytes 公钥的字节形式* @return* @throws Exception*/private static PublicKey getPublicKey(byte[] bytes) throws Exception {bytes = Base64.getDecoder().decode(bytes);X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);KeyFactory factory = KeyFactory.getInstance("RSA");return factory.generatePublic(spec);}/*** 获取密钥** @param bytes 私钥的字节形式* @return* @throws Exception*/private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {bytes = Base64.getDecoder().decode(bytes);PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);KeyFactory factory = KeyFactory.getInstance("RSA");return factory.generatePrivate(spec);}/*** 根据密文,生存rsa公钥和私钥,并写入指定文件** @param publicKeyFilename  公钥文件路径* @param privateKeyFilename 私钥文件路径* @param secret             生成密钥的密文*/public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");SecureRandom secureRandom = new SecureRandom(secret.getBytes());keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom);KeyPair keyPair = keyPairGenerator.genKeyPair();// 获取公钥并写出byte[] publicKeyBytes = keyPair.getPublic().getEncoded();publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes);writeFile(publicKeyFilename, publicKeyBytes);// 获取私钥并写出byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes);writeFile(privateKeyFilename, privateKeyBytes);}private static byte[] readFile(String fileName) throws Exception {return Files.readAllBytes(new File(fileName).toPath());}private static void writeFile(String destPath, byte[] bytes) throws IOException {File dest = new File(destPath);if (!dest.exists()) {dest.createNewFile();}Files.write(dest.toPath(), bytes);}
}

SpringSecurity+JWT+RSA分布式认证思路分析

SpringSecurity主要是通过过滤器来实现功能的!我们要找到SpringSecurity实现认证和校验身份的过滤器! 回顾集中式认证流程

用户认证

使用UsernamePasswordAuthenticationFilter过滤器中attemptAuthentication方法实现认证功能,该过滤 器父类中successfulAuthentication方法实现认证成功后的操作。

身份校验

使用BasicAuthenticationFilter过滤器中doFilterInternal方法验证是否登录,以决定能否进入后续过滤器。 分析分布式认证流程

用户认证

由于,分布式项目,多数是前后端分离的架构设计,我们要满足可以接受异步post的认证请求参数,需要修 改UsernamePasswordAuthenticationFilter过滤器中attemptAuthentication方法,让其能够接收请求体。

另外,默认successfulAuthentication方法在认证通过后,是把用户信息直接放入session就完事了,现在我 们需要修改这个方法,在认证通过后生成token并返回给用户。

身份校验

原来BasicAuthenticationFilter过滤器中doFilterInternal方法校验用户是否登录,就是看session中是否有用 户信息,我们要修改为,验证用户携带的token是否合法,并解析出用户信息,交给SpringSecurity,以便于 后续的授权功能可以正常使用。

SpringSecurity分布式整合之实现思路分析相关推荐

  1. SpringSecurity分布式整合之jwt和rsa说明

    JWT介绍 概念说明 从分布式认证流程中,我们不难发现,这中间起最关键作用的就是token,token的安全与否,直接关系到系统的 健壮性,这里我们选择使用JWT来实现token的生成和校验. JWT ...

  2. SpringSecurity分布式整合之资源服务器搭建和测试

    资源服务 说明 资源服务可以有很多个,这里只拿产品服务为例,记住,资源服务中只能通过公钥验证认证.不能签发token! 创建产品服务并导入jar包 根据实际业务导包即可,咱们就暂时和认证服务一样了. ...

  3. SpringSecurity分布式整合之认证服务配置文件编写和测试

    编写SpringSecurity配置类 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled=tru ...

  4. SpringSecurity分布式整合之分布式认证流程说明

    分布式认证概念说明 分布式认证,即我们常说的单点登录,简称SSO,指的是在多应用系统的项目中,用户只需要登录一次,就可以访 问所有互相信任的应用系统. 分布式认证流程图 首先,我们要明确,在分布式项目 ...

  5. SpringSecurity分布式整合之认证模块搭建

    认证服务 创建认证服务工程并导入jar包 <?xml version="1.0" encoding="UTF-8"?> <project xm ...

  6. SpringSecurity分布式整合之common工具模块创建

    通用模块 创建通用子模块并导入JWT相关jar包 <?xml version="1.0" encoding="UTF-8"?> <projec ...

  7. SpringSecurity分布式整合之验证认证的过滤器

    编写检验token过滤器 public class JwtVerifyFilter extends BasicAuthenticationFilter {private RsaKeyPropertie ...

  8. Elasticsearch 分布式搜索引擎 -- 数据同步:数据同步思路分析 实现elasticsearch与数据库数据同步

    文章目录 1. 数据同步思路分析 1.1 同步调用 1.2 异步通知 1.3 监听binlog 1.4 小结 2. 实现数据同步 2.1 导入hotel-admin 2.2 声明交换机.队列 1)引入 ...

  9. SpringBoot+SpringSecurity+JWT整合实现单点登录SSO史上最全详解

    作者:波波烤鸭 blog.csdn.net/qq_38526573/article/details/103409430 一.什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是 ...

最新文章

  1. 使用Xshell连接Linux服务器
  2. StringGrid数据导出到Excel
  3. go python java_一文助你搞懂参数传递原理解析(java、go、python、c++)
  4. 数学,原来可以这么美!
  5. 7-40 奥运排行榜 (25 分)(详解+思路+map+vector做法)兄弟们冲压呀呀呀呀呀呀呀
  6. 2018.11.27 元器件选型(2)- 连接器
  7. Dij_heap__前向星。
  8. 如何在Mac 上的“自动操作”中使用所选文件创建工作流程?
  9. 环境搭建:通过repo下载gerrit管理的code
  10. 陈冠希英文道歉信难词深度剖析
  11. 《深入浅出WPF》学习笔记之一
  12. mysql修改视图字段长度_SQL Server 数据库创建视图时修改字段长度
  13. MATLAB基础篇——线性代数应用
  14. 快速给pdf生成书签
  15. c++ 容器、继承层次、句柄类
  16. 对称密钥加密、非对称密钥加密、混合加密机制
  17. css less使用
  18. 计算机专业新手小白学编程如何选择笔记本电脑
  19. NoteExpress使用教程及添加参考文献自动跳转超链接
  20. java dismiss_Android dialogFragment dismiss()报错

热门文章

  1. C++类中使用new及delete小例子
  2. Java面试题系列之Java基础类库(一)
  3. vue中前端处理token过期的方法与axios请求拦截处理
  4. Android APK反编译 apktool使用教程
  5. From 百度知道 SQLSERVER 字符集排序规则简单说明
  6. [转]自定义ASP.NET MVC Html辅助方法
  7. JAVA 客户端跳转与服务器端跳转 get与post
  8. webstrom中的快捷键
  9. [PE格式分析] 3.IMAGE_NT_HEADER
  10. Centos7.0上搭建LAMP平台安装discuz后无法访问