Spring Boot 集成并开发 Sa-token

51 篇文章 3 订阅

1 Spring Boot集成Sa-token

1.1 前言

Sa-token是一款高可用的权限认证框架,他带我们用最简化的配置完成用 spring security 需要进行大量配置的才能完成的工作。

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。

官网:https://sa-token.dev33.cn/
源码:https://gitee.com/dromara/sa-token

1.2 集成Sa-token

在我们的基础开发版本中,我们只需要引入最基础依赖,现在的最新官方版本为:1.30.0 建议使用最新版本,如果在你的maven 仓库中没有该版本,需要替换maven 的镜像源,请参考

<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.30.0</version>
</dependency>

配置依赖后需要配置spring boot本地自定义配置

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

按该配置,配置完成后即可完成基础的引入,这里主要配置token 的过期和作用范围。

token:服务端生成的一串加密字符串、以作客户端进行请求的一个“令牌”。. 当用户第一次使用账号密码成功进行登录后,服务器便生成一个Token及Token失效时间并将此返回给客户端,若成功登陆,以后客户端只需在有效时间内带上这个Token前来请求数据即可,无需再次带上用户名和密码。

1.3 基础使用

校验是否成功引入可在启动类下添加该语句

@SpringBootApplication
@EnableScheduling
public class CretApplication {
    public static void main(String[] args) {
        SpringApplication.run(CretApplication.class, args);
				System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
    }
}

当控制台输出我们的配置内容时,证明sa-token 的依赖已经引入,观察输出就会发现sa-token 已经为我们初始化了很多的配置,接下的使用就会非常的简单!

启动成功:Sa-Token配置如下:SaTokenConfig [tokenName=satoken, timeout=2592000, activityTimeout=-1, isConcurrent=true, isShare=true, maxLoginCount=12, isReadBody=true, isReadHead=true, isReadCookie=true, tokenStyle=uuid, dataRefreshPeriod=30, tokenSessionCheckLogin=true, autoRenew=true, tokenPrefix=null, isPrint=true, isLog=false, jwtSecretKey=null, idTokenTimeout=86400, basic=, currDomain=null, checkIdToken=false, cookie=SaCookieConfig [domain=null, path=null, secure=false, httpOnly=false, sameSite=null]]

作为一个权限校验开发框架,他的第一个动作便是针对我们的登录操作,在登录的时候便需要开始使用sa-token里面很强大的一个类‘ StpUtil.class’

// 会话登录:参数填写要登录的账号id,建议的数据类型:long | int | String, 
不可以传入复杂类型,如:UserAdmin 等等
StpUtil.login(Object id);   

// 当前会话注销登录
StpUtil.logout();

// 获取当前会话是否已经登录,返回true=已登录,false=未登录
StpUtil.isLogin();

// 检验当前会话是否已经登录, 如果未登录,则抛出异常:`NotLoginException`
StpUtil.checkLogin();

只需要通过简单的一句登录,sa-token便已经为我们生成好权限校验的系列组件。如果你觉得这种代码方式的开发太繁琐,不是那么的清晰知道当前的权限,进行简单的校验,就可以开启注解方式的校验。注解式校验的配置如下:

@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
    // 注册Sa-Token的注解拦截器,打开注解式鉴权功能
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关)
        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
    }
}

在开启拦截器后,我们即可实现注解式开发,像之前使用spring 注解一般。

// 检验当前会话是否已经登录
StpUtil.checkLogin();

//检验当前会话是否已经登录
@SaCheckLogin

这里的注解可直接放在一个接口上,这样当一个请求进来的时候sa-token 的拦截器会先从请求中获取自己注入 的标识 sa-token ,这个sa-token 里面包含了系列参数来保证登录的安全正确性。

2 Spring Boot开发Sa-token

上一部分我们介绍了如何通过sa-token 实现最基础的登录认证,在开发过程中我们会对sa-token 的一系列功能进行使用,慕歌将就自己的项目向大家展示sa-token 的一些功能,如登录校验、登录检测、封禁用户,token 校验,多租户模式等功能

2.1 导入maven依赖

        <!-- Sa-Token 整合 Redis (使用 jdk 默认序列化方式) -->
        <dependency>
            <groupId>cn.dev33</groupId>
            <artifactId>sa-token-dao-redis</artifactId>
            <version>1.30.0</version>
        </dependency>

        <!-- redis 缓存操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--连接池依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

2.2 权限校验

在进行登录验证的同时,进行权限校验也是重要的一环,sa-token通过拦截器,为我们的权限校验进行了拓展,让我们可以在全局工程中随处进行权限控制。并且依赖于上一节介绍的注解式开发,使得整个校验过程更加的简洁,明了。

/**
 * 注入权限组
 */
@Component
public class StpInterfaceImpl implements StpInterface {
    //权限
    @Autowired
    AdminPowerMapper adminPowerMapper;
    //角色
    @Autowired
    AdminRolesMapper adminRolesMapperl;

    /**
     * 用户权限
     * @param loginId 登录id
     * @param s
     * @return
     */
    @Override
    public List<String> getPermissionList(Object loginId, String s) {
        //获得登录的用户id 对应权限
        List<String> userPermissions = adminPowerMapper.getUserPermissions(loginId);
        System.out.println("permiassion - list : "+userPermissions);
        return userPermissions;
    }

    /**
     * 用户角色
     * @param loginId 登录id
     * @param s
     * @return
     */
    @Override
    public List<String> getRoleList(Object loginId, String s) {
        //获得登录的用户id 对应角色
        List<String> userRoles = adminRolesMapperl.getUserRole(loginId);
        System.out.println("role - list : "+userRoles);
        return userRoles;
    }
}

在我的开发中,引入了两层控制,角色表,权限表,进行细颗粒的权限控制,更好保证数据见的隔离。附上我的角色表于权限表的设计源码:

create table cf_admin_power
(
    id          int unsigned auto_increment comment '权限id'
        primary key,
    code        varchar(32)                not null comment '权限码',
    name        char(32)                   not null comment '权限名',
    level       char(32)                   not null comment '等级',
    icon        varchar(255)               null comment '图标',
    is_show     tinyint unsigned default 1 not null comment '是否显示(0:否,1:是)',
    status      tinyint unsigned default 1 not null comment '状态(1:可用,2:停用,3:已删除)',
    create_time datetime                   not null comment '创建时间',
    update_time datetime                   not null comment '更新时间'
)
    comment '权限表
' collate = utf8_unicode_ci;

-- auto-generated definition
create table cf_admin_roles
(
    id          int unsigned auto_increment comment '角色id'
        primary key,
    name        char(32)                   not null comment '角色名称',
    role_info   char(32)                   null comment '角色描述',
    is_super    tinyint unsigned default 0 not null comment '是超级管理员(1:是,0:否)',
    status      tinyint unsigned default 1 not null comment '状态(1:可用,2:停用,3:已删除)',
    create_time datetime                   null comment '创建时间',
    update_time datetime                   null comment '更新时间'
)
    comment '角色组表' collate = utf8_unicode_ci;

在为用户注入权限后,权限的校验就变得简单起来了,只需要简单的注解,调用即可校验权限。就在这样的一个校验注解,就可以实现用户角色,用户权限的检查

// 角色认证:必须具有指定角色才能进入该方法 
@SaCheckRole("super-admin")     
// 权限认证:必须具有指定权限才能进入该方法 
@SaCheckPermission("user-add") 
//三个权限并列,满足一个则通过
@SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.OR)
//同时满足角色和权限,通过
@SaCheckPermission(value = "user-add", orRole = "admin") 

2.3 token

框架为我们提供了多种token生成方式,以及token 的校验规则,将一个用户标记为登录状态后,该用户就进入sa-token 中进行统一管理。在配置redis 后,即可实现到重启数据不丢失,而且保证分布式环境下多节点的会话一致性。

//登录
StpUtil.login(user.getId());
// 踢下线
StpUtil.kickout(adminUser.getId());
//冻结
StpUtil.disable(adminUser.getId(), -1);
// 获取 Token  相关参数
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

在前后台的开发中,我们可以将登录信息回传,即可实现前端通过token 建立访问,前后端分离。前端可将登录后返回的token 保存,之后每次进行数据访问时携带token ,后端便可以对请求者的权限信息校验。

//回传数据
"data":{11 items
	"tokenName":"satoken"
	"tokenValue":"6046ddd3-71cd-4509-b9ca-b842790bda72"
	"isLogin":true
	"loginId":"1002"
	"loginType":"login"
	"tokenTimeout":2592000
	"sessionTimeout":2591999
	"tokenSessionTimeout":-2
	"tokenActivityTimeout":-1
	"loginDevice":"default-device"
	"tag":NULL
}
//redis 缓存数据
satoken:login:token:6046ddd3-71cd-4509-b9ca-b842790bda72

2.4 多租户模式

在我的开发中,分官网用户和后台用户,他们是完全不同的两组数据,具有各自独立的权限,这时候需要使用到多租户模式,对不同的用户组维护各自的权限。sa-token为我们实现了一种简单的方式,对不同的组加上对应的标签。之后实现sa-token 的校验模式,便可同标准使用方式一样,对自己的用户组校验。

public class StpAdminUtil {
        //权限组 类型 admin
        public static final String TYPE = "admin";
        //底层logic 静态类
        public static StpLogic stpLogic = new StpLogic("admin");

        public StpAdminUtil() {
        }

        public static String getLoginType() {
            return stpLogic.getLoginType();
        }

        public static void setStpLogic(StpLogic stpLogic) {
            cn.dev33.satoken.stp.StpUtil.stpLogic = stpLogic;
            SaManager.putStpLogic(stpLogic);
        }
}

/**
 * 聚合接口
 */
@Configuration
public class SaMultiConfig {
    @Autowired
    public void rewriteSaStrategy() {
        // 重写Sa-Token的注解处理器,增加注解合并功能
        SaStrategy.me.getAnnotation = (element, annotationClass) -> {
            return AnnotatedElementUtils.getMergedAnnotation(element, annotationClass);
        };
    }
}

/**
 * 登录认证(User版):只有登录之后才能进入该方法
 * <p> 可标注在函数、类上(效果等同于标注在此类的所有方法上)
 */
@SaCheckLogin(type = "admin")
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaAdminCheckLogin {
}
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
集成 sa-token 可以让 Spring Boot 应用快速实现权限认证、RBAC、SSO、踢人下线等功能。下面是集成的步骤: 1. 引入 sa-token 的依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>cn.dev33.satoken</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.22.1-RELEASE</version> </dependency> ``` 2. 配置 sa-token 在 application.properties 或 application.yml 文件中添加以下配置: ```yaml # sa-token 配置 sa-token: # token 持久化类型:0-内存版、1-redis版、2-mongodb版、3-jwt版 store-type: 1 # redis 配置 redis: mode: standalone host: 127.0.0.1 port: 6379 database: 0 timeout: 0 # 其他配置... ``` 其中,store-type 表示 sa-token 的持久化类型,可以选择内存版、redis版、mongodb版或 jwt 版。此处选择了 redis 版。 3. 开启 sa-tokenSpring Boot 应用启动类上加上 @SaTokenApplication 注解即可开启 sa-token 的功能: ```java @SpringBootApplication @SaTokenApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 4. 使用 sa-token 现在,我们可以在代码中使用 sa-token 提供的 API 来实现权限认证、RBAC、SSO、踢人下线等功能了。比如: ```java @RestController public class MyController { // 登录接口 @PostMapping("/login") public String login(String account, String password) { // 模拟登录 if ("admin".equals(account) && "123456".equals(password)) { // 登录成功,生成token String token = SaTokenManager.createToken(account); // 返回token return token; } else { // 登录失败 return "账号或密码错误"; } } // 需要登录才能访问的接口 @GetMapping("/user") public String user() { // 获取当前登录账号 String account = SaTokenManager.getAccount(); // 返回当前登录账号 return "当前登录账号:" + account; } // 需要权限才能访问的接口 @GetMapping("/admin") public String admin() { // 检查是否具有admin角色 boolean isAdmin = SaTokenManager.hasRole("admin"); if (isAdmin) { return "欢迎管理员访问"; } else { return "没有访问权限"; } } // 注销登录接口 @PostMapping("/logout") public String logout() { // 注销登录 SaTokenManager.logout(); return "注销成功"; } } ``` 以上是使用 sa-token 的基本示例,你可以根据自己的需求,使用 sa-token 提供的更多 API 实现更复杂的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴名氏.

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值