Spring Boot 3 + Spring Security 6 + JWT 打造企业级权限系统(拿走即用)

🧭 一、前言

在现代前后端分离项目中,用户认证与权限控制是绕不开的话题。传统的基于 Session 的方案在微服务或跨域环境下显得笨重、不灵活。为了解决这些问题,我们采用 Spring Boot 3.x 搭配 Spring Security 6.x,通过 JWT 实现无状态的认证体系,并集成方法级权限注解、Token 自动续期与黑名单控制机制,构建一个安全、高效、可扩展的权限系统。


🛠 二、技术选型与项目结构

🔧 技术栈

  • Spring Boot 3.x
  • Spring Security 6.x
  • JSON Web Token (jjwt)
  • MyBatis + MySQL
  • Redis(可选,用于 Token 黑名单)

📁 模块结构图

arduino 复制代码
com.example.demo
├── config
│   └── SecurityConfig.java
├── controller
│   ├── AuthController.java
│   ├── DemoController.java
│   └── HelloController.java
├── entity
│   └── User.java
├── filter
│   └── JwtAuthenticationFilter.java
├── handler
│   ├── CustomAccessDeniedHandler.java
│   └── CustomLoginFailureHandler.java
├── mapper
│   └── UserMapper.java
├── point
│   └── CustomAuthenticationEntryPoint.java
├── service
│   └── MyUserDetailsService.java
├── utils
│   ├── JwtUtils.java
│   └── TokenBlacklist.java
└── SecurityDemoApplication.java

🔐 三、功能实现详解

3.1 用户登录与 Token 生成

用户通过 /auth/login 接口提交用户名密码,系统验证通过后,签发一个包含用户名和角色信息的 JWT:

scss 复制代码
String token = Jwts.builder()
    .setSubject(username)
    .claim("role", role)
    .setIssuedAt(now)
    .setExpiration(expiry)
    .signWith(key, SignatureAlgorithm.HS256)
    .compact();

前端需将该 Token 保存在本地(如 localStorage)并在后续请求中通过:

makefile 复制代码
Authorization: Bearer xxxxxx

方式传递。


3.2 JWT 鉴权流程

JWT 鉴权通过 JwtAuthenticationFilter 实现,它继承 OncePerRequestFilter,会在每次请求时验证 Token 的合法性,并将用户信息注入 Spring Security 上下文中:

ini 复制代码
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
    Claims claims = jwtUtils.parseToken(token);
    // 验证通过后构建Authentication对象
    UsernamePasswordAuthenticationToken authToken = ...
    SecurityContextHolder.getContext().setAuthentication(authToken);
}

📝 流程图(可视化):

rust 复制代码
前端 -> 登录接口 -> JWT签发 -> 保存Token
     -> 带Token访问受保护接口 -> 过滤器校验 -> 放行或拒绝

3.3 方法级权限控制

Spring Security 支持使用 @PreAuthorize 注解实现方法级权限控制:

less 复制代码
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin")
public String adminApi() {
    return "管理员接口";
}

确保在 SecurityConfig 中启用:

css 复制代码
@EnableMethodSecurity

3.4 Token 自动续期

每次成功访问受保护接口时,过滤器判断 Token 剩余时间是否低于阈值(如10分钟),如果是则自动签发新 Token 并通过响应头 X-Refresh-Token 返回:

ini 复制代码
if (jwtUtils.shouldRefresh(claims.getExpiration())) {
    String newToken = jwtUtils.generateToken(username, role);
    response.setHeader("X-Refresh-Token", newToken);
}

📌 前端监听 X-Refresh-Token 并自动更新本地 Token。


3.5 Token 黑名单机制

用户退出登录时,将当前 Token 加入黑名单(可用 Redis 设置自动过期):

bash 复制代码
redisTemplate.opsForValue().set("blacklist:" + token, "1", ttl, TimeUnit.MILLISECONDS);

在过滤器中拒绝黑名单内的 Token:

kotlin 复制代码
if (redisTemplate.hasKey("blacklist:" + token)) {
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    return;
}

✅ 黑名单使用 Redis TTL 自动过期,无需手动清理。


3.6 登录失败与未授权处理

自定义以下处理器统一返回 JSON 格式错误信息:

错误类型 处理器类 HTTP 状态码
未登录或无效 Token CustomAuthenticationEntryPoint 401
权限不足 CustomAccessDeniedHandler 403
登录失败(账号密码错误) CustomLoginFailureHandler 401

📌 示例返回 JSON:

css 复制代码
{
  "code": 401,
  "message": "未登录或Token无效"
}

🧱 四、常见问题与解决方案

  • AuthenticationManager Bean 不存在?
    ✅ 手动构造并通过 @Bean 注入
  • ❓ JWT 密钥长度报错?
    ✅ 使用 Keys.secretKeyFor(SignatureAlgorithm.HS256) 或 ≥32位字符串
  • ❓ 本地和远程仓库历史不同?
    git pull origin main --allow-unrelated-histories

📌 五、总结与扩展

本文完整实现了一个支持 JWT 无状态认证的权限系统,涵盖了登录认证、方法级授权、Token 自动续期、黑名单强退、异常统一处理等核心功能,具备良好的扩展性与实战价值。

📈 可扩展方向:

  • OAuth2 第三方登录(如 Gitee / GitHub / 企业微信)
  • 单点登录(SSO)
  • 菜单/按钮级动态权限控制(RBAC 权限模型)
  • 登录日志 / Token 活跃追踪 / 多终端限制

🧷 六、源码地址

👉 Gitee 地址:https://gitee.com/nidayeyo/spring-security-demo

如果你觉得本项目对你有帮助,欢迎 Star、Fork 并留言交流~ 🙌

相关推荐
草履虫建模5 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
qq_297574677 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端
老毛肚7 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
学嵌入式的小杨同学7 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
lang201509287 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
Re.不晚8 小时前
Java入门17——异常
java·开发语言
缘空如是8 小时前
基础工具包之JSON 工厂类
java·json·json切换
追逐梦想的张小年8 小时前
JUC编程04
java·idea
好家伙VCC8 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
南极星10059 小时前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言