Spring Boot 集成 Sa-Token 实现登录认证与 RBAC 权限控制(实战)

一、前言

完整实例代码及测试界面

下载地址:https://github.com/yzk2356911358-svg/sa-token

在后台管理系统、ERP、OA 等项目中,权限认证几乎是必不可少的模块。

传统方案中,很多项目会使用 Spring SecurityShiro,但实际开发中你会发现:

  • Spring Security 学习成本高、配置复杂

  • Shiro 已停止活跃维护(尤其在 Spring Boot 3 之后)

Sa-Token 作为一款国产轻量级权限认证框架:

  • API 简单

  • 注解清晰

  • 非侵入式

  • 非常适合 中小型后台系统 / 内部管理系统

本文将通过一个 Spring Boot + Sa-Token + JPA + MySQL 的实战项目,讲解:

如何快速实现 登录认证 + RBAC 权限控制


二、Sa-Token 简介

Sa-Token 是一个 轻量级 Java 权限认证框架,核心功能包括:

  • 登录认证

  • 会话管理

  • 权限校验

  • 角色校验

  • 单点登录

  • 踢人下线

官方理念很明确:

只做权限认证,不接管你的业务

这也是它比 Spring Security 更灵活、更易上手的原因。


三、项目技术栈

  • Spring Boot 3.x

  • Sa-Token 1.38.x

  • Spring Data JPA

  • MySQL

  • Thymeleaf

项目目标:

✔ 登录 / 退出

✔ 登录态校验

✔ RBAC(用户 / 角色 / 权限)

✔ 注解式权限控制


四、RBAC 数据模型设计

经典 RBAC(Role-Based Access Control)模型:

复制代码

用户(User) → 角色(Role) → 权限(Permission)

1️⃣ 用户表(sys_user)

复制代码

id | username | password

2️⃣ 角色表(sys_role)

复制代码

id | code | name

3️⃣ 权限表(sys_permission)

复制代码

id | code | name

4️⃣ 关系表

  • 用户-角色:sys_user_role

  • 角色-权限:sys_role_permission


五、引入 Sa-Token 依赖

pom.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.5.10-SNAPSHOT</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example.rbac</groupId>
	<artifactId>sa-token</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sa-token</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
		<dependency>
			<groupId>cn.dev33</groupId>
			<artifactId>sa-token-spring-boot3-starter</artifactId>
			<version>1.38.0</version>
		</dependency>
		
		<!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
		<dependency>
			<groupId>cn.dev33</groupId>
			<artifactId>sa-token-redis-jackson</artifactId>
			<version>1.38.0</version>
		</dependency>
		
		<!-- 提供Redis连接池 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
		
		<!-- Sa-Token 整合 jwt  -->
		<dependency>
			<groupId>cn.dev33</groupId>
			<artifactId>sa-token-jwt</artifactId>
			<version>1.38.0</version>
		</dependency>
		
		<!-- Spring Security Crypto -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-crypto</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<releases>
				<enabled>false</enabled>
			</releases>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<releases>
				<enabled>false</enabled>
			</releases>
		</pluginRepository>
	</pluginRepositories>

</project>

六、Sa-Token 基础配置

复制代码
复制代码
spring:
  application:
    name: sa-token
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/sa_token?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: rootroot
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect

sa-token:
  # token名称 (同时也是cookie名称)
  token-name: satoken
  # token有效期,单位s 默认30天, -1代表永久有效
  timeout: 2592000
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  active-timeout: -1
  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
  is-share: false
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: true

server:
  port: 8080

七、登录认证实现

1️⃣ 登录逻辑

复制代码

@Service public class AuthService { @Resource private UserRepository userRepository; public boolean login(String username, String password) { User user = userRepository.findByUsername(username); if (user == null || !user.getPassword().equals(password)) { return false; } StpUtil.login(user.getId()); return true; } }

2️⃣ Controller

复制代码

@PostMapping("/login") public String doLogin(String username, String password) { if (authService.login(username, password)) { return "redirect:/index"; } return "login"; }


八、登录态校验(核心)

Sa-Token 的优势之一就是 注解式鉴权

登录校验

复制代码

@SaCheckLogin @GetMapping("/index") public String index() { return "index"; }

未登录访问时,Sa-Token 会直接返回 401。


九、Sa-Token + RBAC 权限控制

1️⃣ 实现 StpInterface

复制代码

@Component public class StpInterfaceImpl implements StpInterface { @Resource private UserRepository userRepository; @Override public List<String> getPermissionList(Object loginId, String loginType) { User user = userRepository.findById((Long) loginId).orElse(null); if (user == null) return List.of(); return user.getRoles().stream() .flatMap(role -> role.getPermissions().stream()) .map(Permission::getCode) .distinct() .toList(); } @Override public List<String> getRoleList(Object loginId, String loginType) { User user = userRepository.findById((Long) loginId).orElse(null); if (user == null) return List.of(); return user.getRoles().stream() .map(Role::getCode) .toList(); } }


2️⃣ 权限注解控制接口

复制代码

@SaCheckPermission("user:add") @PostMapping("/user/add") public String addUser() { return "ok"; }

3️⃣ 角色校验

复制代码

@SaCheckRole("admin") @GetMapping("/admin") public String adminPage() { return "admin"; }


十、Thymeleaf 中的权限控制

Sa-Token 提供了 Thymeleaf 工具类:

复制代码

<li th:if="${#sa.hasPermission('user:list')}"> 用户管理 </li>

这样可以实现 前端菜单级权限控制


十一、Sa-Token 的优点总结

✔ API 简单,学习成本低

✔ 注解式鉴权,代码清晰

✔ 不侵入 Spring Security 体系

✔ 适合后台管理系统、内部系统

✔ 国人维护,中文文档完善


十二、适用场景

  • ERP / OA 系统

  • 内部管理后台

  • 运维平台

  • 中小型后台项目

如果你不想被 Spring Security 的配置折磨,Sa-Token 是一个非常好的选择


十三、结语

Sa-Token 并不是要取代 Spring Security,而是给了开发者一个 更轻、更自由的权限认证选择

对于大多数后台管理系统来说:

Sa-Token + RBAC = 足够、清晰、好维护

相关推荐
小王师傅662 小时前
【轻松入门SpringBoot】actuator健康检查(上)
java·spring boot·后端
码事漫谈3 小时前
C++高并发编程核心技能解析
后端
码事漫谈3 小时前
C++与浏览器交织-从Chrome插件到WebAssembly,开启性能之门
后端
JIngJaneIL3 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
源代码•宸3 小时前
goframe框架签到系统项目(BITFIELD 命令详解、Redis Key 设计、goframe 框架教程、安装MySQL)
开发语言·数据库·经验分享·redis·后端·mysql·golang
⑩-3 小时前
SpringCloud-Nacos 配置中心实战
后端·spring·spring cloud
Jerry5 小时前
Jetpack Compose Navigation
android
java1234_小锋5 小时前
[免费]SpringBoot+Vue勤工助学管理系统【论文+源码+SQL脚本】
spring boot·后端·mybatis·勤工助学
介一安全5 小时前
【Frida Android】实战篇17:Frida检测与绕过——基于inline hook的攻防实战
android·网络安全·逆向·安全性测试·frida