SpringBoot 整合 Sa-Token 实现权限认证——轻量级替代 Shiro

发布时间:2026/7/1 19:23:35
SpringBoot 整合 Sa-Token 实现权限认证——轻量级替代 Shiro 权限认证是每个后台系统都绕不过去的功能。Shiro 配置繁琐、Spring Security 学习曲线陡峭。Sa-Token 是一个轻量级的 Java 权限认证框架API 设计简洁几行代码就能集成到 SpringBoot 中。一、Sa-Token 简介相比 Spring Security 和 ShiroSa-Token 最大的优势就是简单功能Sa-TokenShiroSpring Security登录认证StpUtil.login()Subject.login()复杂配置权限校验SaCheckPermission配置繁琐PreAuthorize踢人下线StpUtil.kickout()需要自己实现需要自己实现Redis 集成加配置一行要写代码默认支持核心特点零配置、API 简单、内置 Redis 集成、支持 OAuth2。二、快速集成1. 引入依赖dependencygroupIdcn.dev33/groupIdartifactIdsa-token-spring-boot-starter/artifactIdversion1.37.0/version/dependency2. 配置application.ymlsa-token:# token 名称默认 satokentoken-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 或配置类。三、登录认证RestControllerRequestMapping(/auth)publicclassAuthController{/** * 登录接口 */PostMapping(/login)publicResultVOStringlogin(RequestParamStringusername,RequestParamStringpassword){// 校验用户名密码这里以 admin/123456 为例if(!admin.equals(username)||!123456.equals(password)){returnResultVO.error(401,用户名或密码错误);}// 执行登录Sa-Token 自动生成 tokenStpUtil.login(1001);// 参数为用户ID// 获取 token 返回给前端StringtokenStpUtil.getTokenInfo().getTokenValue();returnResultVO.success(token);}/** * 退出登录 */PostMapping(/logout)publicResultVO?logout(){StpUtil.logout();returnResultVO.success(退出成功);}/** * 获取当前登录用户信息 */GetMapping(/info)publicResultVO?info(){// 获取当前用户IDlonguserIdStpUtil.getLoginIdAsLong();returnResultVO.success(当前用户: userId);}}前端请求时在 header 中携带 tokenAuthorization: satoken Content-Type: application/json四、拦截器配置需要登录才能访问ConfigurationpublicclassSaTokenConfigimplementsWebMvcConfigurer{OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){// 注册 Sa-Token 的路由拦截器registry.addInterceptor(newSaInterceptor()).addPathPatterns(/**).excludePathPatterns(/auth/login,// 登录接口不拦截/auth/register,/doc.html,// Swagger 文档/v3/**,/swagger-ui/**);}}配置后所有未登录的请求会返回401 未登录不需要自己写拦截器。五、权限认证1. 给用户分配权限ServicepublicclassUserService{/** * 获取用户的权限列表从数据库查询 */publicListStringgetPermissions(LonguserId){// 实际项目中从数据库查询if(userId1001){returnArrays.asList(user.add,user.delete,user.update,user.query);}returnArrays.asList(user.query);}/** * 获取用户的角色列表 */publicListStringgetRoles(LonguserId){if(userId1001){returnArrays.asList(admin);}returnArrays.asList(user);}}2. 注册权限接口ComponentpublicclassStpInterfaceImplimplementsStpInterface{AutowiredprivateUserServiceuserService;/** * 获取用户的权限列表框架自动调用 */OverridepublicListStringgetPermissionList(ObjectloginId,StringloginType){LonguserIdLong.parseLong(loginId.toString());returnuserService.getPermissions(userId);}/** * 获取用户的角色列表 */OverridepublicListStringgetRoleList(ObjectloginId,StringloginType){LonguserIdLong.parseLong(loginId.toString());returnuserService.getRoles(userId);}}3. 使用注解控制权限RestControllerRequestMapping(/user)publicclassUserController{GetMapping(/list)SaCheckPermission(user.query)// 需要 user.query 权限publicResultVO?list(){returnResultVO.success(查询用户列表);}PostMapping(/add)SaCheckPermission(user.add)// 需要 user.add 权限publicResultVO?add(){returnResultVO.success(新增用户);}DeleteMapping(/delete)SaCheckPermission(user.delete)// 需要 user.delete 权限publicResultVO?delete(){returnResultVO.success(删除用户);}PutMapping(/update)SaCheckPermission(user.update)// 需要 user.update 权限publicResultVO?update(){returnResultVO.success(修改用户);}}4. 角色校验GetMapping(/admin/dashboard)SaCheckRole(admin)// 只有 admin 角色能访问publicResultVO?dashboard(){returnResultVO.success(管理后台面板);}5. 在代码中手动校验// 校验是否有权限没有则抛异常StpUtil.checkPermission(user.add);// 校验权限返回 booleanif(StpUtil.hasPermission(user.delete)){// 有权限就执行}// 校验角色StpUtil.checkRole(admin);六、踢人下线管理员可以强制让某个用户下线比如检测到异常登录PostMapping(/kickout)SaCheckRole(admin)publicResultVO?kickout(LonguserId){// 让指定用户被踢下线StpUtil.kickout(userId);returnResultVO.success(已强制用户 userId 下线);}被踢的用户下次请求时会收到401提示Token 已被踢下线。七、记住我7天免登录// 登录时设置 rememberMe truetoken 有效期自动延长StpUtil.login(1001,true);// 不传或 false 则使用配置的 timeoutStpUtil.login(1001);在配置中设置记住我的时长sa-token:# 记住我模式的有效期单位秒7天activity-timeout:604800八、单点登录SSOSa-Token 内置了单点登录方案几行配置就能实现多系统统一登录sa-token:sso:# SSO 认证中心地址auth-url:http://sso-server.com:9000/auth# 是否开启单点登录is-sso:true详细用法参考 Sa-Token 官方文档sso 章节。九、与你的秒杀系统集成RestControllerRequestMapping(/api/seckill)SaCheckLogin// 整个类需要登录才能访问publicclassSeckillController{PostMapping(/do/{productId})SaCheckPermission(seckill.buy)// 需要秒杀权限publicResultVO?doSeckill(PathVariableLongproductId){// 获取当前登录用户longuserIdStpUtil.getLoginIdAsLong();returnseckillService.doSeckill(productId,userId,用户userId);}}只用加两个注解权限控制就搞定了。比之前可能用的拦截器Session 方式省事很多。十、Sa-Token 常用 API 速查// 登录认证StpUtil.login(1001);// 登录StpUtil.logout();// 登出StpUtil.getLoginId();// 获取当前用户IDStpUtil.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();// 获取当前 tokenStpUtil.getTokenInfo();// 获取 token 详细信息总结Sa-Token 的核心就两句话——StpUtil.login()登录SaCheckPermission鉴权。比 Shiro 的 Subject Realm 配置文件那一套简洁太多了。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。