IntelliJ+SpringBoot项目实战(十四)--在SpringBoot中整合SpringSecurity和JWT(上)

[复制链接]
发表于 2025-12-20 08:04:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
        SpringSecurity是台甫鼎鼎的认证授权框架,在SSH期间就已经大放异彩。在JAVA项目中,权限框架的办理方案重要是以SpringSecurity和Shiro为主。JWT是现在主流的基于access-token的的认证框架,在项目中一样平常时SpringSecurity和JWT联合利用,在前后端分离的架构中,利用JWT作为认证框架更为广泛。
        本文先容在SpringBoot中整合SpringSecurity和JWT框架的完备流程。
一、增长依靠包
    起首在openjweb-core工程的pom.xml里增长SpringSecurity干系的依靠:
  1.         <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             <artifactId>spring-boot-starter-security</artifactId>
  4.         </dependency>
  5.         <dependency>
  6.             <groupId>org.springframework.boot</groupId>
  7.             <artifactId>spring-boot-starter-data-redis</artifactId>
  8.         </dependency>
  9.         <!--这个代码实现中会用到-->
  10.         <dependency>
  11.             <groupId>org.springframework.boot</groupId>
  12.             <artifactId>spring-boot-starter-validation</artifactId>
  13.         </dependency>
复制代码
         别的背面的示例代码中会用到jwt、HuTool工具类库等,放到openjweb-common公共模块包,这些包根本是大部分Java项目开辟中都要用到的,把下面的依靠加到openjweb-common的pom.xml:
  1.         <!-- jwt -->
  2.         <dependency>
  3.             <groupId>io.jsonwebtoken</groupId>
  4.             <artifactId>jjwt</artifactId>
  5.             <version>0.9.1</version>
  6.         </dependency>
  7.         <dependency>
  8.             <groupId>com.github.axet</groupId>
  9.             <artifactId>kaptcha</artifactId>
  10.             <version>0.0.9</version>
  11.         </dependency>
  12.         <!-- hutool工具类-->
  13.         <dependency>
  14.             <groupId>cn.hutool</groupId>
  15.             <artifactId>hutool-all</artifactId>
  16.             <version>5.3.3</version>
  17.         </dependency>
  18.         <dependency>
  19.             <groupId>org.apache.commons</groupId>
  20.             <artifactId>commons-lang3</artifactId>
  21.             <version>3.12.0</version> <!--3.11 is error-->
  22.         </dependency>
  23.         <dependency>
  24.             <groupId>org.apache.commons</groupId>
  25.             <artifactId>commons-lang3</artifactId>
  26.         </dependency>
  27.         <dependency>
  28.             <groupId>commons-codec</groupId>
  29.             <artifactId>commons-codec</artifactId>
  30.             <version>1.15</version>
  31.         </dependency>
  32.         <dependency>
  33.             <groupId>org.projectlombok</groupId>
  34.             <artifactId>lombok</artifactId>
  35.         </dependency>
复制代码
         下面我们先看下整合到这一步运行的结果,启动openjweb-sys的应用,然后访问我们在前面章节先容的任意一个接口,比方: http://localhost:8001/api/cms/cmsInfo/queryCom,我们会发现哀求定向到了一个登录页面,这个登录页面是Spring Security的默认登录页面:

        此时我们还没设置用户脚色等,那么这个界面输入什么口令登录,就是Spring Security提供的默认的登录账号和暗码,这个用户名和暗码是什么呢?不是admin和123456,暗码是SpringBoot启动的时间,控制台中天生的一个暗码,看启动界面:

        在登录界面中输入用户名user (不是admin),暗码是上图标红的暗码,输入乐成后,会调用访问接口返回的实验结果:

        在现实项目开辟中,我们肯定要筹划我们自己的用户、脚色、权限、脚色权限关系表。以是我们背面须要筹划干系的数据库表。接下来我们须要实现的代码比力多。可以按下面的步调开辟。
二、Jwt工具类
       起首我们开辟一个Jwt工具类,用于登录时将登录账号天生对应的access_token,以及根据access_token反向分析出登录账号。
        在开辟Jwt工具类之前,先在openjweb-sys的pom.xml中设置几个jwt须要用到的变量。变量在控制层通过@Value注解引入,以是须要先在openjweb-sys的pom.xml中增长一个依靠:
        
  1.         <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             <artifactId>spring-boot-configuration-processor</artifactId>
  4.             <optional>true</optional>
  5.         </dependency>
复制代码
        先开辟一个Jwt工具类,用来天生Jwt,分析Jwt,判定Jwt是否逾期,Jwt工具类可以放到openjweb-core下面的org.openjweb.core.util下,见下面的代码:
  1. package org.openjweb.core.util;
  2. import io.jsonwebtoken.*;
  3. import lombok.Data;
  4. import java.util.Date;
  5. @Data
  6. public class JwtUtil {
  7.     private long expire;
  8.     private String secret;
  9.     private String header;
  10.     public JwtUtil(){}
  11.     /**
  12.      *
  13.      * @param header 头部
  14.      * @param secert 加密私钥
  15.      * @param expire 过期秒数
  16.      */
  17.     public JwtUtil(String header,String secert,long expire){
  18.         this.expire = expire;
  19.         this.header = header;
  20.         this.secret = secert;
  21.     }
  22.     // 生成JWT
  23.     public String generateToken(String username) {
  24.         Date nowDate = new Date();
  25.         Date expireDate = new Date(nowDate.getTime() + 1000 * expire);
  26.         return Jwts.builder()
  27.                 .setHeaderParam("typ", "JWT")
  28.                 .setSubject(username)
  29.                 .setIssuedAt(nowDate)
  30.                 .setExpiration(expireDate)    // 过期时间
  31.                 .signWith(SignatureAlgorithm.HS512, secret)
  32.                 .compact();
  33.     }
  34.     // 解析JWT
  35.     public Claims getClaimsByToken(String jwt) {
  36.         try {
  37.             return Jwts.parser()
  38.                     .setSigningKey(secret)
  39.                     .parseClaimsJws(jwt)
  40.                     .getBody();
  41.         } catch (Exception e) {
  42.             return null;
  43.         }
  44.     }
  45.     // 判断JWT是否过期
  46.     public boolean isTokenExpired(Claims claims) {
  47.         return claims.getExpiration().before(new Date());
  48.     }
  49. }
复制代码
        然后在openjweb-sys的application-dev.yml增长jwt的设置,包罗header(设置认证方式)、secret加密密钥、expire逾期时间。见下面设置:

        然后我们开辟一个API接口类用于jwt的测试,在openjweb-b2b2c的org.openjweb.b2c.api下创建RedisDemoApi,至于为什么在b2c模块中建这个测试类,是为了演示在其他子模块中也能读取到openjweb-sys的application-dev.yml中的设置:
  1. package org.openjweb.b2c.api;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.openjweb.common.response.ResponseResult;
  4. import org.openjweb.core.util.JwtUtil;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. @RestController
  9. @RequestMapping("/api/jwt/")
  10. @Slf4j
  11. public class JwtDemoApi {
  12.     @Value("${jwt.expire}")
  13.     private long expire;
  14.     @Value("${jwt.secret}")
  15.     private String secret;
  16.     @Value("${jwt.header}")
  17.     private String header;
  18.     ////localhost:8001/api/jwt/testjwt?loginId=admin
  19.     @RequestMapping("/testjwt")
  20.     public ResponseResult testJwt(String loginId) {
  21.         String str = "";
  22.         log.info("开始调用testjwt::");
  23.         log.info("配置里读header");
  24.         log.info(header);
  25.         log.info(secret);
  26.         log.info(String.valueOf(expire));
  27.         JwtUtil jwtUtil = new JwtUtil(header, secret, expire);
  28.          str = jwtUtil.generateToken(loginId);
  29.         //检查是否读取了配置文件的参数
  30.         log.info("测试账号转jwt:");
  31.         log.info(str);
  32.         return ResponseResult.okResult(str);
  33.     }
  34. }
复制代码
      上面代码中,通过@Value注解从application-dev.yml中获取设置的值,在测试方法testJwt中,通过log.info输入的信息可以看到读取的内容,然后通过newJwtUtil构造函数对登录账号举行加密,然后输入加密后的accessToken。下面是测试所在:localhost:8001/api/jwt/testjwt?loginId=admin
        测试后的界面输出:

        data是返回的access_token。那么怎样从access_token中分析用户账号呢?利用下面的代码分析登录账号:
        String loginId = jwtUtil.getClaimsByToken(str).getSubject();
由于篇幅比力长,本文先先容到这里,背面再增长2篇文章接续先容SpringSecurity+JWT 整合。
本文的示例代码见Github: https://github.com/openjweb/cloud/tree/master
https://github.com/openjweb/cloud/tree/master


回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表