SpringSecurity+jwt+captcha登录认证授权总结

SpringSecurity+jwt+captcha登录认证授权总结

版本信息:

springboot 3.2.0、springSecurity 6.2.0、mybatis-plus 3.5.5

认证授权思路和流程:
未携带token,访问登录接口:

1、用户登录携带账号密码

2、请求到达自定义Filter,自定义Filter(如JwtAuthenticationTokenFilter)继承OncePerRequestFilter(此Filter只会进行一次过滤,在请求返回时,不会再进行调用),在SecurityConfig中配置,将自定义Filter添加到过滤器链中并加在UsernamePasswordAuthenticationFilter过滤器之前

3、自定义Filter逻辑

3.1、查询到用户未携带token,直接放行,进入到后面认证流程

3.2、将用户信息封装成Authentication对象,调用authticate()方法进行验证,一直到DaoAuthenticationProvider中,会调用UserDetailService的loadUserByUserName()方法;自定义UserDetailServiceImpl继承UserDetailService接口;重写其loadUserByUserName()方法;查到用户后,封装成UserDetail对象返回

4、调用passwordEncoder的验证方法进行用户信息的认证(一般使用BCryptPasswordEncoder,创建此Bean并放入容器中)

5、认证通过后,使用JWT创建token并放到redis中;返回token到前端

携带token访问:

1、请求到达自定义Filter中,获取token,先验证token的正确性,从token中获取到userId,根据userId从redis中获取用户信息,将用户信息封装成Authentication对象,放进SecurityContextHolder中,后面的过滤器会在SecurityContextHolder中获取用户的信息

2、请求到达FilterSecurityInterceptor,在springSecurity中默认使用FilterSecurityInterceptor来进行权限校验;FilterSecurityInterceptor会从SecurityContextHolder中获取Authentication,然后获取其中的权限信息,判断当前用户是否拥有当前资源的访问权限;

3、通过权限判断,获取资源返回给前端;

登录认证流程图:

在这里插入图片描述

基于RBAC的授权控制:
RBAC概念:

Role-Based Access Control,中文意思是:基于角色(Role)的访问控制。这是一种广泛应用于计算机系统和网络安全领域的访问控制模型。

简单来说,就是通过将权限分配给角色,再将角色分配给用户,来实现对系统资源的访问控制。一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般是多对多的关系

模型:

在这里插入图片描述

在数据库中主要体现用户表角色表菜单表用户角色关联表角色菜单关联表五个模型:

CREATE TABLE "mySchema"."t_user"
(
"id" INT IDENTITY(1, 1) NOT NULL,
"username" VARCHAR(100) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"email" VARCHAR(100) NOT NULL,
"phone" VARCHAR(100),
UNIQUE("id"),
UNIQUE("username"),
UNIQUE("email"),
UNIQUE("phone"),
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;COMMENT ON TABLE "mySchema"."t_user" IS '用户表';
COMMENT ON COLUMN "mySchema"."t_user"."id" IS '用户id';
COMMENT ON COLUMN "mySchema"."t_user"."username" IS '用户名';
COMMENT ON COLUMN "mySchema"."t_user"."password" IS '密码';
COMMENT ON COLUMN "mySchema"."t_user"."email" IS '用户邮箱';
COMMENT ON COLUMN "mySchema"."t_user"."phone" IS '电话';CREATE TABLE "mySchema"."sys_role"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"name" VARCHAR(128) DEFAULT NULL,
"role_key" VARCHAR(100) DEFAULT NULL,
"status" CHAR(1) DEFAULT '0',
"del_flag" INT DEFAULT 0,
"create_by" BIGINT DEFAULT NULL,
"create_time" DATETIME(6) DEFAULT NULL,
"update_by" BIGINT DEFAULT NULL,
"update_time" DATETIME(6) DEFAULT NULL,
"remark" VARCHAR(500) DEFAULT NULL,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;COMMENT ON TABLE "mySchema"."sys_role" IS '角色表';
COMMENT ON COLUMN "mySchema"."sys_role"."id" IS '角色id';
COMMENT ON COLUMN "mySchema"."sys_role"."name" IS '角色名称';
COMMENT ON COLUMN "mySchema"."sys_role"."role_key" IS '角色权限字符串';
COMMENT ON COLUMN "mySchema"."sys_role"."status" IS '角色状态(0正常, 1停用)';
COMMENT ON COLUMN "mySchema"."sys_role"."del_flag" IS '删除标志(0未删除,1已删除)';
COMMENT ON COLUMN "mySchema"."sys_role"."remark" IS '备注';CREATE TABLE "mySchema"."sys_menu"
(
"id" BIGINT IDENTITY(2, 1) NOT NULL,
"menu_name" VARCHAR(64) DEFAULT 'NULL' NOT NULL,
"path" VARCHAR(200) DEFAULT NULL,
"component" VARCHAR(50) DEFAULT NULL,
"visible" CHAR(1) DEFAULT '0',
"status" CHAR(1) DEFAULT '0',
"perms" VARCHAR(100) DEFAULT NULL,
"icon" VARCHAR(100) DEFAULT '#',
"create_by" BIGINT DEFAULT NULL,
"create_time" DATETIME(6) DEFAULT CURRENT_TIMESTAMP,
"update_by" BIGINT DEFAULT NULL,
"update_time" DATETIME(6) DEFAULT CURRENT_TIMESTAMP,
"delete_f1ag" INT DEFAULT 0,
"remark" VARCHAR(500) DEFAULT NULL,
UNIQUE("id"),
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;COMMENT ON TABLE "mySchema"."sys_menu" IS '菜单表';
COMMENT ON COLUMN "mySchema"."sys_menu"."menu_name" IS '菜单名';
COMMENT ON COLUMN "mySchema"."sys_menu"."path" IS '路由地址';
COMMENT ON COLUMN "mySchema"."sys_menu"."component" IS '组件路径';
COMMENT ON COLUMN "mySchema"."sys_menu"."visible" IS '菜单状态(0显示1隐藏)';
COMMENT ON COLUMN "mySchema"."sys_menu"."status" IS '菜单状态(0正常1停用)';
COMMENT ON COLUMN "mySchema"."sys_menu"."perms" IS '权限标识';
COMMENT ON COLUMN "mySchema"."sys_menu"."icon" IS '菜单图标';
COMMENT ON COLUMN "mySchema"."sys_menu"."delete_f1ag" IS '是否删除(0未删除1已删除)';
COMMENT ON COLUMN "mySchema"."sys_menu"."remark" IS '备注';CREATE TABLE "mySchema"."sys_user_role"
(
"user_id" BIGINT DEFAULT 0 NOT NULL,
"role_id" BIGINT DEFAULT 0 NOT NULL,
NOT CLUSTER PRIMARY KEY("user_id", "role_id")) STORAGE(ON "MAIN", CLUSTERBTR) ;COMMENT ON TABLE "mySchema"."sys_user_role" IS '用户角色表';
COMMENT ON COLUMN "mySchema"."sys_user_role"."user_id" IS '用户id';
COMMENT ON COLUMN "mySchema"."sys_user_role"."role_id" IS '角色id';CREATE TABLE "mySchema"."sys_role_menu"
(
"role_id" BIGINT DEFAULT 0 NOT NULL,
"menu_id" BIGINT DEFAULT 0 NOT NULL,
NOT CLUSTER PRIMARY KEY("role_id", "menu_id")) STORAGE(ON "MAIN", CLUSTERBTR) ;COMMENT ON TABLE "mySchema"."sys_role_menu" IS '角色菜单关联表';
COMMENT ON COLUMN "mySchema"."sys_role_menu"."role_id" IS '角色id';
COMMENT ON COLUMN "mySchema"."sys_role_menu"."menu_id" IS '菜单id';

权限流程:

用户表、角色表、菜单表、部门表、用户角色关联表、角色菜单关联表;数据权限分为5种:个人、全部、本部门、指定部门、本部门及以下
链路:

1、用户注册,指定部门;创建角色,给角色赋菜单权限、数据权限;给用户赋予角色;
2、用户登录,通过用户的所有角色,获取所有的菜单权限和最大数据权限;菜单数据直接展示在页面;所有数据都有创建人,则数据的部门id是创建人的部门id;
3、在访问数据接口时,通过mybatis的拦截器对用户的数据进行过滤(拼接sql),返回给前端;

captcha图片验证码:

实现思路:

1、图片验证码获取,并将验证码验证码存放起来(单机应用可放在session中,分布式应用放在redis中)

2、当用户登录时,携带验证码以及验证码的key,进入到后端从redis中获取值进行验证

<!-- 谷歌kaptcha验证码依赖 -->
<dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version>
</dependency>

代码思路:

1、生成验证码

public Result<CaptchaVO> getCaptcha() throws IOException {// 生成文字验证码String content = defaultKaptcha.createText();// 生成图片验证码ByteArrayOutputStream outputStream = null;BufferedImage image = defaultKaptcha.createImage(content);outputStream = new ByteArrayOutputStream();ImageIO.write(image, "jpg", outputStream);// 对字节数组Base64编码String str = "data:image/jpeg;base64,";String base64Img = str + Base64.getEncoder().encodeToString(outputStream.toByteArray()).replace("\n", "").replace("\r", "");CaptchaVO captchaVO = captchaService.cacheCaptcha(content);captchaVO.setBase64Img(base64Img);return Result.success(captchaVO);
}

2、存储验证码

@Service
public class CaptchaService {private Long timeout = 300L;@Autowiredprivate RedisUtils redisUtils;private final String CAPTCHA_KEY_PREFIX = "captcha:verification:";public CaptchaVO cacheCaptcha(String captcha){//生成一个随机标识符String randomStr = UUID.randomUUID().toString();//缓存验证码并设置过期时间String captchaKey = CAPTCHA_KEY_PREFIX.concat(randomStr);redisUtils.set(captchaKey, captcha, timeout, TimeUnit.SECONDS);CaptchaVO captchaVO = new CaptchaVO();captchaVO.setCaptchaKey(captchaKey);captchaVO.setExpire(timeout);captchaVO.setCaptcha(captcha);return captchaVO;}
}

3、校验验证码

Object captcha = redisUtils.get(reqVO.getCaptchaKey());
if (Objects.isNull(captcha)) {return "验证码已过期";
}
if (!captcha.equals(reqVO.getCaptcha())) {return "验证码错误";
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机视觉和机器人技术中的下一个标记预测与视频扩散相结合

一种新方法可以训练神经网络对损坏的数据进行分类&#xff0c;同时预测下一步操作。 它可以为机器人制定灵活的计划&#xff0c;生成高质量的视频&#xff0c;并帮助人工智能代理导航数字环境。 Diffusion Forcing 方法可以对嘈杂的数据进行分类&#xff0c;并可靠地预测任务的…

2024-11-17 -MATLAB三维绘图简单实例

1. x -1:0.05:1; y x; [X, Y] meshgrid(x, y); f (X, Y) (sin(pi * X) .* sin(pi * Y)) .^ 2.*sin(2.*X2.*Y); mesh(X, Y, f(X, Y)); % 调用函数f并传递X和Y xlabel(X-axis); ylabel(Y-axis); zlabel(Z-axis); title(Surface Plot of (sin(pi * X) .* sin(pi * Y)) .^ 2.*…

WebAssembly在桌面级应用开发中的探索与实践

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 WebAssembly在桌面级应用开发中的探索与实践 WebAssembly在桌面级应用开发中的探索与实践 WebAssembly在桌面级应用开发中的探索…

第二十一周学习周报

目录 摘要Abstract1. LSTM原理2. LSTM反向传播的数学推导3. LSTM模型训练实战总结 摘要 本周的学习内容是对LSTM相关内容的复习&#xff0c;LSTM被设计用来解决标准RNN在处理长序列数据时遇到的梯度消失和梯度爆炸问题。LSTM通过引入门控机制来控制信息的流动&#xff0c;从而…

《Spring 基础之 IoC 与 DI 入门指南》

一、IoC 与 DI 概念引入 Spring 的 IoC&#xff08;控制反转&#xff09;和 DI&#xff08;依赖注入&#xff09;在 Java 开发中扮演着至关重要的角色&#xff0c;是提升代码质量和可维护性的关键技术。 &#xff08;一&#xff09;IoC 的含义及作用 IoC 全称为 Inversion of…

Vulnhub靶场案例渗透[9]- HackableIII

文章目录 一、靶场搭建1. 靶场描述2. 下载靶机环境3. 靶场搭建 二、渗透靶场1. 确定靶机IP2. 探测靶场开放端口及对应服务3. 扫描网络目录结构4. 敏感数据获取5. 获取shell6. 提权6.1 敏感信息获取6.2 lxd提权 一、靶场搭建 1. 靶场描述 Focus on general concepts about CTF…

抖音热门素材去哪找?优质抖音视频素材网站推荐!

是不是和我一样&#xff0c;刷抖音刷到停不下来&#xff1f;越来越多的朋友希望在抖音上创作出爆款视频&#xff0c;但苦于没有好素材。今天就来推荐几个超级实用的抖音视频素材网站&#xff0c;让你的视频内容立刻变得高大上&#xff01;这篇满是干货&#xff0c;直接上重点&a…

如何轻松导出所有 WordPress URL 为纯文本格式

作为一名多年的 WordPress 使用者&#xff0c;我深知管理一个网站的复杂性。从迁移网站、设置重定向到整理内容结构&#xff0c;每一步都需要精细处理。而拥有所有 URL 的清单&#xff0c;不仅能让这些工作变得更加简单&#xff0c;还能为后续的管理提供极大的便利。其实&#…

vue项目使用eslint+prettier管理项目格式化

代码格式化、规范化说明 使用eslintprettier进行格式化&#xff0c;vscode中需要安装插件ESLint、Prettier - Code formatter&#xff0c;且格式化程序选择为后者&#xff08;vue文件、js文件要分别设置&#xff09; 对于eslint规则&#xff0c;在格式化时不会全部自动调整&…

Ubuntu 18.04 配置sources.list源文件(无法安全地用该源进行更新,所以默认禁用该源)

如果你 sudo apt update 时出现诸如 无法安全地用该源进行更新&#xff0c;所以默认禁用该源 的错误&#xff0c;那就换换源吧&#xff0c;链接&#xff1a; https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/ 注意版本&#xff1a; 修改源文件&#xff1a; sudo nano /etc…

5. langgraph中的react agent使用 (从零构建一个react agent)

1. 定义 Agent 状态 首先&#xff0c;我们需要定义 Agent 的状态&#xff0c;这包括 Agent 所持有的消息。 from typing import (Annotated,Sequence,TypedDict, ) from langchain_core.messages import BaseMessage from langgraph.graph.message import add_messagesclass …

【网络】什么是交换机?switch

交换机&#xff08;Switch&#xff09;意为“开关”&#xff0c;是一种用于电&#xff08;光&#xff09;信号转发的网络设备。以下是关于交换机的详细解释&#xff1a; 一、交换机的基本定义 功能&#xff1a;交换机能为接入交换机的任意两个网络节点提供独享的电信号通路&am…

【AlphaFold3】开源本地的安装及使用

文章目录 安装安装DockerInstalling Docker on Host启用Rootless Docker 安装 GPU 支持安装 NVIDIA 驱动程序安装 NVIDIA 对 Docker 的支持 获取 AlphaFold 3 源代码获取基因数据库获取模型参数构建将运行 AlphaFold 3 的 Docker 容器 参考 AlphaFold3: https://github.com/goo…

【免越狱】iOS砸壳 可下载AppStore任意版本 旧版本IPA下载

软件介绍 下载iOS旧版应用&#xff0c;简化繁琐的抓包流程。 一键生成去更新IPA&#xff08;手机安装后&#xff0c;去除App Store的更新检测&#xff09;。 软件界面 支持系统 Windows 10/Windows 8/Windows 7&#xff08;由于使用了Fiddler库&#xff0c;因此需要.Net环境…

shell 100例

1、每天写一个文件 (题目要求&#xff09; 请按照这样的日期格式(xxxx-xx-xx每日生成一个文件 例如生成的文件为2017-12-20.log&#xff0c;并且把磁盘的使用情况写到到这个文件中不用考虑cron&#xff0c;仅仅写脚本即可 [核心要点] date命令用法 df命令 知识补充&#xff1…

Acrobat Pro DC 2023(pdf免费转化word)

所在位置 通过网盘分享的文件&#xff1a;Acrobat Pro DC 2023(64bit).tar 链接: https://pan.baidu.com/s/1_m8TT1rHTtp5YnU8F0QGXQ 提取码: 1234 --来自百度网盘超级会员v4的分享 安装流程 打开安装所在位置 进入安装程序 找到安装程序 进入后点击自定义安装&#xff0c;这里…

linux之调度管理(5)-实时调度器

一、概述 在Linux内核中&#xff0c;实时进程总是比普通进程的优先级要高&#xff0c;实时进程的调度是由Real Time Scheduler(RT调度器)来管理&#xff0c;而普通进程由CFS调度器来管理。 实时进程支持的调度策略为&#xff1a;SCHED_FIFO和SCHED_RR。 SCHED_FIFO&#xff…

在arm64架构下, Ubuntu 18.04.5 LTS 用命令安装和卸载qt4、qt5

问题&#xff1a;需要在 arm64下安装Qt&#xff0c;QT源码编译失败以后&#xff0c;选择在线安装&#xff01; 最后安装的版本是Qt5.9.5 和QtCreator 4.5.2 。 一、ubuntu安装qt4的命令(亲测有效)&#xff1a; sudo add-apt-repository ppa:rock-core/qt4 sudo apt updat…

Qt 之 qwt和QCustomplot对比

QWT&#xff08;Qt Widgets for Technical Applications&#xff09;和 QCustomPlot 都是用于在 Qt 应用程序中绘制图形和图表的第三方库。它们各有优缺点&#xff0c;适用于不同的场景。 以下是 QWT 和 QCustomPlot 的对比分析&#xff1a; 1. 功能丰富度 QWT 功能丰富&a…

实用教程:如何无损修改MP4视频时长

如何在UltraEdit中搜索MP4文件中的“mvhd”关键字 引言 在视频编辑和分析领域&#xff0c;有时我们需要深入到视频文件的底层结构中去。UltraEdit&#xff08;UE&#xff09;和UEStudio作为强大的文本编辑器&#xff0c;允许我们以十六进制模式打开和搜索MP4文件。本文将指导…