SaToken认证授权快速上手

news2024/9/20 1:10:25

SA-TOKEN认证授权快速上手

  • SaToken简介
  • 认证授权实现
    • 1 创建5张测试基础表
    • 2 配置文件
    • 3 Sa-Token的全局拦截器
    • 4 自定义权限认证接口扩展
    • 5 SaToken用户控制层
  • 测试验证
    • 用户2登录验证权限
    • 用户1登录验证权限
    • 项目代码结构

SaToken简介

SaToken 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。Sa-Token 旨在以简单、优雅的方式完成系统的权限认证部分。SaToken官网,原理如下
请添加图片描述

认证授权实现

1 创建5张测试基础表

利用经典RBAC理论,创建5张基础表,用于模拟用户的角色和权限功能。
users用户表
在这里插入图片描述
role角色表
在这里插入图片描述
role_users角色用户表
在这里插入图片描述
promission权限表
在这里插入图片描述
role_promission角色权限表
在这里插入图片描述

可以看到
用户1zhangsan拥有admin和guest角色,拥有user-read、user-write、product-read、product-read四个权限。
用户2拥有guest角色,拥有user-read、product-read两个权限。

2 配置文件

pom.xml引入依赖

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

application-dev.yml增加配置

############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
sa-token:
  # token 名称(同时也是 cookie 名称)
  token-name: satoken
  # token 有效期(单位:秒) 默认30天,-1 代表永久有效
  timeout: 2592000
  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
  active-timeout: -1
  # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
  is-share: true
  # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
  token-style: uuid
  # 是否输出操作日志
  is-log: true

3 Sa-Token的全局拦截器

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    // 注册 Sa-Token 拦截器,打开注解式鉴权功能
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 拦截器,打开注解式鉴权功能
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }
}

4 自定义权限认证接口扩展

自定义接口实现SaToken框架的StpInterface接口,自动帮我们进行执行业务逻辑(获取权限集合,获取角色集合)

/**
 * 自定义权限认证接口扩展,Sa-Token 将从此实现类获取每个账号拥有的权限码
 * 只要实现了SaToken的StpInterface接口,
 * 并且加了@Component被SpringBoot管理,框架就会自动帮我们进行执行业务逻辑
 *
 * @author huahua
 * @since 2024/8/23
 */
@Component
public class StpInterfaceImpl implements StpInterface {

    @Resource
    private JdbcTemplate jdbcTemplate;

    // 权限认证校验SaCheckPermission,SaCheckRole注解,必须具有指定权限才能进入该方法。
    // 可以标注在方法、类上(效果等同于标注在此类的所有方法上)

    /**
     * 根据登录id和登录类型获取用户权限列表,返回一个账号所拥有的 权限 码集合
     * <p>
     * 该方法通过查询数据库,获取指定用户所拥有的所有权限代码
     * 查询涉及3张自定义报表:role_user角色用户关联表、role_promission角色权限关联表、promisssion权限表
     * 查询条件为用户id,连接3个表获取当前用户所有角色权限信息,从而提取权限代码
     *
     * @param loginId   用户登录id
     * @param loginType 登录类型
     * @return 权限列表
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        System.out.println("读取权限列表");
        List<String> list = new ArrayList<>();
        // 通过用户id查询此id对应的权限列表
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select distinct promission_code from role_users ru,role_promission rp,promission p" +
                " where ru.role_id = rp.role_id and rp.promission_id = p.permission_id and ru.user_id = ?", loginId);
        for (Map<String, Object> map : maps) {
            list.add(map.get("promission_code").toString());
        }
        return list;
    }

    /**
     * 根据登录id和登录类型获取用户权限列表,返回一个账号所拥有的 角色 码集合
     *
     * @param loginId   用户登录id
     * @param loginType 登录类型
     * @return 角色列表
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        List<String> list = new ArrayList<>();
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select distinct r.role_code from role_users ru,role r where ru.role_id = r.role_id and ru.user_id = ?", loginId);
        for (Map<String, Object> map : maps) {
            list.add(map.get("role_code").toString());
        }
        return list;
    }

}

5 SaToken用户控制层

/**
 * sa-token用户控制层
 *
 * @author huahua
 * @DATE 2024/8/23
 **/
@RestController
@RequestMapping("/user/")
public class UserController {
    @Resource
    private JdbcTemplate jdbcTemplate;

    // 测试登录,浏览器访问: http://localhost:8086/user/doLogin?username=lisi&password=lisi
    @RequestMapping("doLogin")
    public SaResult doLogin(String username, String password) {
        List<Map<String, Object>> list =
                jdbcTemplate.queryForList("select user_id from users where user_name = ? and password = ?", username, password);
        if (list.isEmpty()) {
            return SaResult.error("用户名或密码错误");
        } else {
            StpUtil.login(list.get(0).get("user_id"));
            return SaResult.ok("登录成功");
        }
    }

    // 查询登录状态,浏览器访问: http://localhost:8086/user/isLogin
    @RequestMapping("isLogin")
    public SaResult isLogin() {
        return SaResult.ok("是否登录:" + StpUtil.isLogin());
    }

    /**
     * 查询用户信息接口,需要具备自定义的‘user-query’权限
     *
     * @return SaResult 操作结果,返回成功状态
     */
    @SaCheckPermission("user-read")
    @GetMapping("findUsers")
    public SaResult findUsers() {
        return SaResult.ok();
    }

    /**
     * 创建用户的接口,需具备‘user-write’或'write'权限之一
     * SaMode.AND, 标注一组权限,会话必须全部具有才可通过校验。
     * SaMode.OR, 标注一组权限,会话只要具有其一即可通过校验。
     *
     * @return SaResult 操作结果,返回成功状态
     */
    @SaCheckPermission(value = {"user-write", "write"}, mode = SaMode.OR)
    @GetMapping("createUser")
    public SaResult createUser() {
        /*
        // 查询权限信息 ,如果当前会话未登录,会返回一个空集合
        List<String> permissionList = StpUtil.getPermissionList();
        System.out.println("当前登录账号拥有的所有权限:" + permissionList);

        // 查询角色信息 ,如果当前会话未登录,会返回一个空集合
        List<String> roleList = StpUtil.getRoleList();
        System.out.println("当前登录账号拥有的所有角色:" + roleList);
        */
        return SaResult.ok();
    }

    /**
     * 删除用户
     * 代表需要拥有角色 admin 才可以操作
     *
     * @return SaResult 操作结果,返回成功状态
     */
    @SaCheckRole("admin")
    @GetMapping("/deleteUser")
    public SaResult deleteUser(){
        return SaResult.ok();
    }
}

测试验证

用户2登录验证权限

发现用户2,没有deleteUser和createUser用户权限,因为SaCheckRole和SaCheckPermission框架注解帮我们做了权限管控!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用户1登录验证权限

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目代码结构

项目结构如下,源码demo-springboot-mybatisplus,欢迎star
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【信号】信号的产生

信号的概念 什么是信号&#xff1f;我们生活中的红绿灯&#xff0c;闹钟&#xff0c;外面电话等等这些都是信号&#xff0c;我们是怎么认识这些信号的&#xff0c;我们认识这些信号&#xff0c;并且知道这些信号的处理方法&#xff0c;对于进程来说&#xff0c;也会认识相应的…

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么&#xff1f; K8s的架构原理 控制平面(Control plane) kube-apiserver etcd kube-scheduler kube-controller-manager cloud-controller-manager 小结 节点组件(Node) container runtime Pod kubelet ku…

Chrome、Edge、360及Firefox浏览器加载多个ActiveX插件的介绍

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

vc-align源码分析 -- ant-design-vue系列

vc-align源码分析 源码地址&#xff1a;https://github.com/vueComponent/ant-design-vue/tree/main/components/vc-align 1 基础代码 1.1 名词约定 需要对齐的节点叫source&#xff0c;对齐的目标叫target。 1.2 props 提供了两个参数&#xff1a; align&#xff1a;对…

成为优秀程序员-代码篇

1. 序言 刚毕业参加工作时候&#xff0c;公司正在快速扩张&#xff0c;我入职的时候组内刚刚招了一大波人&#xff0c;当时leader提出集体cr代码来拉齐团队内的编码规范&#xff0c;每当有对于相对重要改动大的项目就会集体cr代码&#xff0c;老板想法初衷是好的&#xff0c;但…

esp32 gpio 初始化不同类型的管脚,产生脉冲,发生中断

硬件&#xff1a;D4与D18 连接&#xff0c;二极管接D15与3.3v脚 图片 二极管同期性点亮&#xff0c;间隔1秒 参考esp32官网程序&#xff0c;从此程序可以看出&#xff0c;中断程序没有处理任何数据&#xff0c;只是把中断发生的事件存入队列。而用另一新线程来处理中断事务。…

GNSS CTS GNSS Start and Location Flow of Android15

目录 1. 本文概述2.CTS 测试3.Gnss Flow3.1 Gnss Start Flow3.2 Gnss Location Output Flow 1. 本文概述 本来是为了做Android 14 Gnss CTS 的相关环境的搭建和测试&#xff0c;然后在测试中遇到了一些问题&#xff0c;去寻找CTS源码(/cts/tests/tests/location/src/android/l…

Vue3-05_组件高级

背景 对组件的进一步了解,如组件之间通信等知识点&#xff0c;根据教程实现购物车功能&#xff0c;并修复原本的bug. watch 侦听器 用途 watch 侦听器允许开发者监视数据的变化&#xff0c;从而针对数据的变化做特定的操作。例如&#xff0c;监视用户名的变化并发起请求&am…

大模型AI一体机对行业的帮助

大模型AI一体机&#xff0c;如AntSKPro AI离线知识库一体机&#xff0c;是专门为企业和机构设计的集成系统&#xff0c;旨在提供高效的人工智能服务。这类一体机通常包含预训练的大型机器学习模型&#xff0c;以及必要的硬件和软件资源&#xff0c;以支持复杂的数据处理和分析任…

maven 编译构建可以执行的jar包

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

网易云音乐歌单下载器

最近要帮小朋友下载一些小学的诗词mp3&#xff0c;找了各种工具&#xff0c;还是这个好使 yun-playlist-downloader: 网易云音乐歌单下载器 特性 支持歌单 / 专辑 / 电台音质选择下载超时 / 重试再次下载默认跳过已下载部分, 使用 content-length 匹配自定义文件名下载进度显…

【代码随想录训练营第42期 Day53打卡 - 图论Part4 - 卡码网 110. 字符串接龙 105. 有向图的完全可达性

目录 一、个人感受 二、题目与题解 题目一&#xff1a;卡码网 110. 字符串接龙 题目链接 题解&#xff1a;BFS哈希 题目二&#xff1a;卡码网 105. 有向图的完全可达性 题目链接 题解&#xff1a;DFS 三、小结 一、个人感受 对于两大基本搜索&#xff1a; 深度优先搜…

JDBC:连接数据库

文章目录 报错 报错 Exception in thread “main” java.sql.SQLException: Can not issue SELECT via executeUpdate(). 最后这里输出的还是地址&#xff0c;就是要重写toString()方法&#xff0c;但是我现在还不知道怎么写 修改完的代码&#xff0c;但是数据库显示&#…

WebGL系列教程二(环境搭建及初始化Shader)

目录 1 前言2 新建html页面3 着色器介绍3.1 顶点着色器、片元着色器与光栅化的概念3.2 声明顶点着色器3.3 声明片元着色器 4 坐标系(右手系)介绍5 着色器初始化5.1 给一个画布canvas5.2 获取WebGL对象5.3 创建着色器对象5.4 获取着色器对象的源5.5 绑定着色器的源5.6 编译着色器…

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页&#xff1a;https://tangyuan96.github.io/minigpt_3d_project_page/ 代码&#xff1a;https://github.com/TangYuan96/MiniGPT-3D 论文&#xff1a;https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA&#xff0c;被ACM MM2024接收&#xff0c;只拥…

佰朔资本:9月首选行业为汽车、电子、医药生物等

5—8月商场接连调整&#xff0c;9月开端进入成绩空窗期&#xff0c;流动性和政策改动从头成为商场中心驱动力&#xff0c;风格切换先行&#xff0c;对当时的商场能够豁达一些。价值和生长风格切换的拐点开始闪现&#xff0c;生长相对价值的成绩优势开端走扩&#xff0c;美联储降…

Axure中继器介绍

中继器我们一般在处理重复性比较高的任务时&#xff0c;能让我们达到事半功倍的效果&#xff0c;中继器在整个axure中属于复杂程度比较高的功能&#xff0c;我们今天大致讲一下常用的方法即可。 一、声明一个中继器 默认展示为三行。 点击样式&#xff0c;这里我们可以添加删…

【原创】java+springboot+mysql校园二手商品交易网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

RestTemplateRibbonOpenFeign

网络模型 OSI七层模型 RestTemplate Ribbon 在微服务中的ribbon 实现负载均衡服务间调用的三种方式 ribbon其他负载均衡策略 OpenFeign 实战

【Shiro】Shiro 的学习教程(五)之 SpringBoot 集成 Shiro + JWT

与 Spring 集成&#xff1a;与 Spring 集成 与 SpringBoot 集成&#xff1a;与 SpringBoot 集成 1、SpringBoot Shiro Jwt ①&#xff1a;引入 pom.xml&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-…