【框架】参考 Spring Security 安全框架设计出,轻量化高可扩展的身份认证与授权架构
关键字:AOP、JWT、自定义注解、责任链模式
一、Spring Security
Spring Security 想必大家并不陌生,是 Spring 家族里的一个安全框架,特别完善,但学习成本比较大,不少开发者都觉得,这个框架“很重”
他的认证授权的过程时使用的 api 和组件比较复杂,但这不是主要的顾虑
并且,他是基于过滤器实现的,其过程抛出的异常并不会被全局异常处理器拦截,通过 SpringSecurity 认证授权的请求,才算进入我们的 Spring 环境下
但不得不说他确实有优点
- 对请求的一个 AOP 的统一处理(但是好像没有专门的后置处理器)
- 可以通过添加过滤器的方式增加认证过程,也对某些路由可添加授权过程
- 框架的一些注解,例如 @PreAuthorize,可以很方便的进行接口权限的设置
虽然它封装了很多现成的东西,但其实一些自己去写也没什么大不了的,还可以按照自己的想法去定制
我们可以学习它的优点去优化一下我们原本的认证授权架构
二、AOP + JWT
通过全局拦截器,拦截所有的请求,请求携带访问令牌 JWT,这里就不必多说了
三、自定义注解
自定义一个可以 Retention 为 Runtime,Target 为 TYPE 或 METHOD 的注解:
- 允许访问的角色
- 是否需要认证
- 是否需要授权
标注在 Controller 类才有用,若加在类上,则作用于所有方法,若标注在方法上,则以方法上的为准
意为此接口的拦截参数
/*** Created With Intellij IDEA* User: 马拉圈* Date: 2024-08-08* Time: 12:50* <br />* permit: 用户必须是列表中的角色才能访问 <br />* authenticate: 用户需不需要通过认证 <br />* authorize: 用户需不需要通过授权 <br />* 注意: <br />* permit 若为 {},则代表谁都不能访问,除非 authorize 为 false <br />* 1. 不需要认证、不需要授权 ✅ <br />* 2. 需要认证、需要授权 ✅ <br />* 3. 需要认证、不需要授权 ✅ <br />* 4. 不需要认证、需要授权 ❌(必然失败) <br />*/
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Intercept {UserType[] permit() default {UserType.NORMAL_USER, UserType.MANAGER};boolean authenticate() default true; // 默认需要认证boolean authorize() default true; // 默认需要授权}
@Slf4j
public class InterceptHelper {public static Intercept getIntercept(Class<?> clazz) {// 类上的 Intercept 为初步结果return clazz.isAnnotationPresent(Intercept.class) ? clazz.getAnnotation(Intercept.class) : null;}public static Intercept getIntercept(Method targetMethod) {// 获取目标方法所在的类Class<?> declaringClass = targetMethod.getDeclaringClass();// 类上的 Intercept 为初步结果Intercept intercept = getIntercept(declaringClass);// 方法上的 Intercept 为最终结果return targetMethod.isAnnotationPresent(Intercept.class) ? targetMethod.getAnnotation(Intercept.class) : intercept;}}
四、责任链模式
责任链:
- 抽象处理者
- 具体处理者
- 客户端(我习惯是责任链的链头)
设计出以下架构:
- 前置初始化链
- 初始化日志变量、设置请求 id、请求 uri、请求方法,便于全链路追踪
- 根据配置文件对特定接口设置的拦截参数,判断当前请求的接口是否被设置了特殊的拦截参数
- 请求的接口如果存在目标方法,则判断其方法上或者类上是否存在 @Intercept 注解,若存在则初始化拦截参数
若不存在拦截参数,则代表该资源没有被开发者专门进行拦截的管理,直接返回错误:api 访问失败
- 前置认证链
- 是否忽略,若 authenticate 参数为 false,则直接忽略
- 若认证未成功且未获取 jwt,则尝试从 header 里获取 jwt
- 若认证未成功且未获取 jwt,则此时从 queryString 里获取 jwt
- 若认证未成功,则解析 jwt,若成功解析出用户信息,则存储到本地线程变量里(若令牌即将过期,则返回一个新的 jwt)
若未认证成功,则返回错误:认证失败
- 前置授权链
- 是否武略
- 是否强制拦截
- 若未授权成功,则获取当前用户的角色,判断是否存在于拦截参数的允许访问的角色列表,若存在则授权成功
若未授权成功,则返回错误:授权失败
- 后置链
- 清除日志变量、本地线程变量
在我们的架构中而一个责任链节点应该包含:
- 拦截的路由
- 执行的前置条件
- 执行的代码
具体代码参考:OKR-System4.0/src/main/java/cn/bitterfree/api/interceptor at main · CarefreeState/OKR-System4.0
相关文章:

【框架】参考 Spring Security 安全框架设计出,轻量化高可扩展的身份认证与授权架构
关键字:AOP、JWT、自定义注解、责任链模式 一、Spring Security Spring Security 想必大家并不陌生,是 Spring 家族里的一个安全框架,特别完善,但学习成本比较大,不少开发者都觉得,这个框架“很重” 他的…...

【Git 学习笔记_27】DIY 实战篇:利用 DeepSeek 实现 GitHub 的 GPG 密钥创建与配置
文章目录 1 前言2 准备工作3 具体配置过程3.1. 本地生成 GPG 密钥3.2. 导出 GPG 密钥3.3. 将密钥配置到 Git 中3.4. 测试提交 4 问题排查记录5 小结与复盘 1 前言 昨天在更新我的第二个 Vim 专栏《Mastering Vim (2nd Ed.)》时遇到一个经典的 Git 操作问题:如何在 …...
微信小程序地图map全方位解析
微信小程序地图map全方位解析 微信小程序的 <map> 组件是一个功能强大的工具,可以实现地图展示、定位、标注、路径规划等多种功能。以下是全方位解析微信小程序地图组件的知识点: 一、地图组件基础 1. 引入 <map> 组件 在页面的 .wxml 文…...
调试无痛入手
在调试过程中,Step In、Step Over 和 Step Out 是控制代码执行流程的常用操作,帮助开发者逐行或逐块检查代码行为。以下是它们的详细介绍及使用方法: 1. Step In 功能:进入当前行的函数或方法内部,逐行执行其代码。使…...
【蓝桥杯集训·每日一题2025】 AcWing 6135. 奶牛体检 python
6135. 奶牛体检 Week 1 2月21日 农夫约翰的 N N N 头奶牛站成一行,奶牛 1 1 1 在队伍的最前面,奶牛 N N N 在队伍的最后面。 农夫约翰的奶牛也有许多不同的品种。 他用从 1 1 1 到 N N N 的整数来表示每一品种。 队伍从前到后第 i i i 头奶牛的…...
AI发展迅速,是否还有学习前端的必要性?
今天有个小伙伴跟我讨论:“现在 AI 发展迅速,是否还有学习 JS 或者 TS 及前端知识的必要?” 我非常肯定地说: 是的,学习 JavaScript/TypeScript 以及前端知识仍然非常必要,而且在可预见的未来,…...

【数据标准】数据标准化是数据治理的基础
导读:数据标准化是数据治理的基石,它通过统一数据格式、编码、命名与语义等,全方位提升数据质量,确保准确性、完整性与一致性,从源头上杜绝错误与冲突。这不仅打破部门及系统间的数据壁垒,极大促进数据共享…...

VS2022配置FFMPEG库基础教程
1 简介 1.1 起源与发展历程 FFmpeg诞生于2000年,由法国工程师Fabrice Bellard主导开发,其名称源自"Fast Forward MPEG",初期定位为多媒体编解码工具。2004年后由Michael Niedermayer接任维护,逐步发展成为包含音视频采…...

three.js之特殊材质效果
*案例42 创建一个透明的立方体 <template><div ref"container" className"container"></div> </template><script setup> import * as THREE from three; import WebGL from three/examples/jsm/capabilities/WebGL.js // 引…...

Qt常用控件之日历QCalendarWidget
日历QCalendarWidget QCalendarWidget 是一个日历控件。 QCalendarWidget属性 属性说明selectDate当前选中日期。minimumDate最小日期。maximumDate最大日期。firstDayOfWeek设置每周的第一天是周几(影响日历的第一列是周几)。gridVisible是否显示日历…...

vxe-table 如何实现跟 Excel 一样的数值或金额的负数自动显示红色字体
vxe-table 如何实现跟 Excel 一样的数值或金额的负数自动显示红色字体,当输入的值为负数时,会自动显示红色字体,对于数值或者金额输入时该功能就非常有用了。 查看官网:https://vxetable.cn gitbub:https://github.co…...

DINOv2 + yolov8 + opencv 检测卡车的可拉拽雨覆是否完全覆盖
最近是接了一个需求咨询图像处理类的,甲方要在卡车过磅的地方装一个摄像头用检测卡车的车斗雨覆是否完全, 让我大致理了下需求并对技术核心做下预研究 开发一套图像处理软件,能够实时监控经过的卡车并判断其车斗的雨覆状态。 系统需具备以下…...

算法日记27:完全背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)
一、暴力搜索(DFS) O ( n 2 ) O(n^2) O(n2) 1.1)思路解析 1、注意和01背包的区别在于每个物品可以无限次选择 注意在完全背包中,当一个物品被选择过一次,我们仍然需要考虑是否继续选择这个物品 01背包: …...
Linux 命令大全完整版(14)
5. 文件管理命令 chgrp(change group) 功能说明:变更文件或目录的所属群组。语 法:chgrp [-cfhRv][–help][–version][所属群组][文件或目录…] 或 chgrp [-cfhRv][–help][–version][–reference<参考文件或目录>][文件或目录…]补充说明&…...

基于 DeepSeek LLM 本地知识库搭建开源方案(AnythingLLM、Cherry、Ragflow、Dify)认知
写在前面 博文内容涉及 基于 Deepseek LLM 的本地知识库搭建使用 ollama 部署 Deepseek-R1 LLM知识库能力通过 Ragflow、Dify 、AnythingLLM、Cherry 提供理解不足小伙伴帮忙指正 😃,生活加油 我站在人潮中央,思考这日日重复的生活。我突然想,…...
Could not initialize class io.netty.util.internal.Platfor...
异常信息: Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class io.netty.util.internal.PlatformDependent0 Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.reflect.InaccessibleObjec…...

【书生大模型实战营】玩转HF/魔搭/魔乐社区-L0G4000
本文是书生大模型实战营系列的第4篇,本文的主题是:玩转HF/魔搭/魔乐社区。 1.开源大模型社区总览 开源不仅仅是一种技术模式,更是一种精神的体现。它打破了知识的壁垒,让技术平权成为可能。近年来,开源大模型社区蓬勃…...
2025年华为手机解锁BL的方法
注:本文是我用老机型测试的,新机型可能不适用 背景 华为官方已经在2018年关闭了申请BL解锁码的通道,所以华为手机已经无法通过官方获取解锁码。最近翻出了一部家里的老手机华为畅玩5X,想着能不能刷个系统玩玩,但是卡…...

了解 RAG 第二部分:经典 RAG 的工作原理
在本系列的第一篇文章中,我们介绍了检索增强生成 (RAG) ,解释了扩展传统大型语言模型 (LLM)功能的必要性。我们还简要概述了 RAG 的核心思想:从外部知识库检索上下文相关的信息,以确保 LLM 生成准确且最新的信息,而不会…...
50周学习go语言:第四周 函数与错误处理深度解析
第四周 函数与错误处理深度解析 以下是第4周函数基础的深度教程,包含两个完整案例和详细实现细节: 第四周:函数与错误处理深度解析 一、函数定义与参数传递 1. 基础函数结构 // 基本语法 func 函数名(参数列表) 返回值类型 {// 函数体 }// …...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...