java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Boot 集成 Sa-token

Spring Boot 集成并开发 Sa-token示例详解

作者:吴名氏.

Sa-token是一款高可用的权限认证框架,他带我们用最简化的配置完成用 spring security 需要进行大量配置的才能完成的工作,这篇文章主要介绍了Spring Boot 集成并开发 Sa-token,需要的朋友可以参考下

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, 
不可以传入复杂类型,如:User、Admin 等等
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 {
}

到此这篇关于Spring Boot 集成并开发 Sa-token的文章就介绍到这了,更多相关Spring Boot 集成 Sa-token内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文