SpringBoot整合Sa-Token实现权限认证的示例代码

 更新时间:2026年07月01日 08:51:54   作者:张老师技术栈  
Sa-Token是一个轻量级Java权限认证框架,相比SpringSecurity和Shiro,配置更简单、API更简洁,本文详细介绍了Sa-Token的快速集成、登录认证、权限校验和踢人下等功能,帮助你快速掌握Sa-Token的用技巧,需要的朋友可以参考下

权限认证是每个后台系统都绕不过去的功能。Shiro 配置繁琐、Spring Security 学习曲线陡峭。Sa-Token 是一个轻量级的 Java 权限认证框架,API 设计简洁,几行代码就能集成到 SpringBoot 中。

一、Sa-Token 简介

相比 Spring Security 和 Shiro,Sa-Token 最大的优势就是简单

功能Sa-TokenShiroSpring Security
登录认证StpUtil.login()Subject.login()复杂配置
权限校验@SaCheckPermission配置繁琐@PreAuthorize
踢人下线StpUtil.kickout()需要自己实现需要自己实现
Redis 集成加配置一行要写代码默认支持

核心特点: 零配置、API 简单、内置 Redis 集成、支持 OAuth2。

二、快速集成

1. 引入依赖

<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.37.0</version>
</dependency>

2. 配置(application.yml)

sa-token:
  # token 名称(默认 satoken)
  token-name: token
  # token 有效期(秒,30天)
  timeout: 2592000
  # token 最低活跃频率(秒,-1 不续签)
  active-timeout: -1
  # 是否允许同一账号多地同时登录(true 允许多端登录)
  is-concurrent: true
  # 多人登录时,是否踢掉已登录的(false 不踢)
  is-share: false
  # token 风格
  token-style: uuid
  # 是否输出操作日志
  is-log: true

就这么两配置,不需要别的 XML 或配置类。

三、登录认证

@RestController
@RequestMapping("/auth")
public class AuthController {

    /**
     * 登录接口
     */
    @PostMapping("/login")
    public ResultVO<String> login(@RequestParam String username,
                                   @RequestParam String password) {
        // 校验用户名密码(这里以 admin/123456 为例)
        if (!"admin".equals(username) || !"123456".equals(password)) {
            return ResultVO.error(401, "用户名或密码错误");
        }

        // 执行登录(Sa-Token 自动生成 token)
        StpUtil.login(1001);  // 参数为用户ID

        // 获取 token 返回给前端
        String token = StpUtil.getTokenInfo().getTokenValue();
        return ResultVO.success(token);
    }

    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public ResultVO<?> logout() {
        StpUtil.logout();
        return ResultVO.success("退出成功");
    }

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/info")
    public ResultVO<?> info() {
        // 获取当前用户ID
        long userId = StpUtil.getLoginIdAsLong();
        return ResultVO.success("当前用户: " + userId);
    }
}

前端请求时在 header 中携带 token:

Authorization: satoken
Content-Type: application/json

四、拦截器配置(需要登录才能访问)

@Configuration
public class SaTokenConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 的路由拦截器
        registry.addInterceptor(new SaInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns(
                    "/auth/login",     // 登录接口不拦截
                    "/auth/register",
                    "/doc.html",       // Swagger 文档
                    "/v3/**",
                    "/swagger-ui/**"
                );
    }
}

配置后,所有未登录的请求会返回 401 未登录,不需要自己写拦截器。

五、权限认证

1. 给用户分配权限

@Service
public class UserService {

    /**
     * 获取用户的权限列表(从数据库查询)
     */
    public List<String> getPermissions(Long userId) {
        // 实际项目中从数据库查询
        if (userId == 1001) {
            return Arrays.asList("user.add", "user.delete", "user.update", "user.query");
        }
        return Arrays.asList("user.query");
    }

    /**
     * 获取用户的角色列表
     */
    public List<String> getRoles(Long userId) {
        if (userId == 1001) {
            return Arrays.asList("admin");
        }
        return Arrays.asList("user");
    }
}

2. 注册权限接口

@Component
public class StpInterfaceImpl implements StpInterface {

    @Autowired
    private UserService userService;

    /**
     * 获取用户的权限列表(框架自动调用)
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        Long userId = Long.parseLong(loginId.toString());
        return userService.getPermissions(userId);
    }

    /**
     * 获取用户的角色列表
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        Long userId = Long.parseLong(loginId.toString());
        return userService.getRoles(userId);
    }
}

3. 使用注解控制权限

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/list")
    @SaCheckPermission("user.query")         // 需要 user.query 权限
    public ResultVO<?> list() {
        return ResultVO.success("查询用户列表");
    }

    @PostMapping("/add")
    @SaCheckPermission("user.add")           // 需要 user.add 权限
    public ResultVO<?> add() {
        return ResultVO.success("新增用户");
    }

    @DeleteMapping("/delete")
    @SaCheckPermission("user.delete")        // 需要 user.delete 权限
    public ResultVO<?> delete() {
        return ResultVO.success("删除用户");
    }

    @PutMapping("/update")
    @SaCheckPermission("user.update")        // 需要 user.update 权限
    public ResultVO<?> update() {
        return ResultVO.success("修改用户");
    }
}

4. 角色校验

@GetMapping("/admin/dashboard")
@SaCheckRole("admin")  // 只有 admin 角色能访问
public ResultVO<?> dashboard() {
    return ResultVO.success("管理后台面板");
}

5. 在代码中手动校验

// 校验是否有权限(没有则抛异常)
StpUtil.checkPermission("user.add");

// 校验权限(返回 boolean)
if (StpUtil.hasPermission("user.delete")) {
    // 有权限就执行
}

// 校验角色
StpUtil.checkRole("admin");

六、踢人下线

管理员可以强制让某个用户下线(比如检测到异常登录):

@PostMapping("/kickout")
@SaCheckRole("admin")
public ResultVO<?> kickout(Long userId) {
    // 让指定用户被踢下线
    StpUtil.kickout(userId);
    return ResultVO.success("已强制用户 " + userId + " 下线");
}

被踢的用户下次请求时会收到 401,提示"Token 已被踢下线"。

七、记住我(7天免登录)

// 登录时设置 rememberMe = true,token 有效期自动延长
StpUtil.login(1001, true);
// 不传或 false 则使用配置的 timeout
StpUtil.login(1001);

在配置中设置记住我的时长:

sa-token:
  # 记住我模式的有效期(单位:秒,7天)
  activity-timeout: 604800

八、单点登录(SSO)

Sa-Token 内置了单点登录方案,几行配置就能实现多系统统一登录:

sa-token:
  sso:
    # SSO 认证中心地址
    auth-url: http://sso-server.com:9000/auth
    # 是否开启单点登录
    is-sso: true

详细用法参考 Sa-Token 官方文档(sso 章节)。

九、与你的秒杀系统集成

@RestController
@RequestMapping("/api/seckill")
@SaCheckLogin  // 整个类需要登录才能访问
public class SeckillController {

    @PostMapping("/do/{productId}")
    @SaCheckPermission("seckill.buy")  // 需要秒杀权限
    public ResultVO<?> doSeckill(@PathVariable Long productId) {
        // 获取当前登录用户
        long userId = StpUtil.getLoginIdAsLong();
        return seckillService.doSeckill(productId, userId, "用户" + userId);
    }
}

只用加两个注解,权限控制就搞定了。 比之前可能用的拦截器+Session 方式省事很多。

十、Sa-Token 常用 API 速查

// 登录认证
StpUtil.login(1001);                    // 登录
StpUtil.logout();                       // 登出
StpUtil.getLoginId();                   // 获取当前用户ID
StpUtil.isLogin();                      // 是否登录
StpUtil.checkLogin();                   // 校验登录(未登录抛异常)

// 权限校验
StpUtil.checkPermission("user.add");    // 校验权限
StpUtil.hasPermission("user.add");      // 是否拥有权限
StpUtil.checkRole("admin");             // 校验角色
StpUtil.hasRole("admin");               // 是否拥有角色

// 踢人
StpUtil.kickout(1001);                  // 踢用户下线
StpUtil.logout(1001);                   // 让用户注销(踢下线且清除记录)

// Token 管理
StpUtil.getTokenValue();                // 获取当前 token
StpUtil.getTokenInfo();                 // 获取 token 详细信息

总结: Sa-Token 的核心就两句话——StpUtil.login() 登录,@SaCheckPermission 鉴权。比 Shiro 的 Subject + Realm + 配置文件那一套简洁太多了。

以上就是SpringBoot整合Sa-Token实现权限认证的示例代码的详细内容,更多关于SpringBoot Sa-Token权限认证的资料请关注脚本之家其它相关文章!

相关文章

  • java实现简单学生管理系统项目

    java实现简单学生管理系统项目

    这篇文章主要介绍了java实现简单学生管理系统项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • java打印当前方法名示例分享

    java打印当前方法名示例分享

    在C与C++中可以打印当前函数名,但在Java没有此说法,一切即对象,得从某个对象中去获取,下面介绍两种方式打印当前方法名
    2014-02-02
  • springboot实现启动直接访问项目地址

    springboot实现启动直接访问项目地址

    这篇文章主要介绍了springboot实现启动直接访问项目地址,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java回溯法解决全排列问题流程详解

    Java回溯法解决全排列问题流程详解

    从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。这篇文章主要介绍了Java回溯法解决全排列问题
    2022-10-10
  • java获得平台相关的行分隔符和java路径分隔符的方法

    java获得平台相关的行分隔符和java路径分隔符的方法

    不同系统平台下的行分隔符、路径分隔符等常常不同,如何在Java程序获取当前平台的分隔符,以及其他系统相关的状态呢?下面是示例程序,需要的朋友可以参考下
    2014-02-02
  • Spring的@ConfigurationProperties注解详解

    Spring的@ConfigurationProperties注解详解

    这篇文章主要介绍了Spring的@ConfigurationProperties注解详解,@ConfigurationProperties该注解是用来获取yml或者properties配置文件的配置信息,下面根据一些配置信息给出案例代码进行讲解,需要的朋友可以参考下
    2023-11-11
  • Java如何操作MongoDB常用API文档

    Java如何操作MongoDB常用API文档

    这篇文章主要介绍了Java如何操作MongoDB常用API文档,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • SpringBoot的@Conditional条件注解详解

    SpringBoot的@Conditional条件注解详解

    这篇文章主要介绍了SpringBoot的@Conditional条件注解详解,打开每个自动配置类,都会看到@Conditional或其衍生的条件注解,本节我们来认识下@Conditional注解,需要的朋友可以参考下
    2023-12-12
  • SpringMVC详解如何映射请求数据

    SpringMVC详解如何映射请求数据

    这篇文章主要给大家介绍了关于SpringMvc映射请求数据的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-06-06
  • Java深入学习图形用户界面GUI之事件处理

    Java深入学习图形用户界面GUI之事件处理

    这篇文章主要介绍了基于Java GUI 事件处理方式,一个图形界面制作完成了,在程序开发中只是完成了起步的工作。要想让一个组件都发挥自己的作用.就必须对所有的组件进行事件处理
    2022-05-05

最新评论