当前位置: 首页 > news >正文

Security方法注解权限控制过程及自定义权限表达式

文章目录

    • 使用内置的权限表达式
      • @PreAuthorize
      • PermissionEvaluator
    • 自定义权限表达式
      • SysMethodSecurityExpressionHandler
        • 源码流程
      • SysMethodSecurityExpressionRoot

使用内置的权限表达式

@PreAuthorize

这个用来判断超级管理员的话,还得在表达式上加上

PermissionEvaluator

本来是想定义一个 PermissionEvaluator,但是发现,写表达式的时候,还得弄2个参数,@PreAuthorize(‘/admin/user/list’,‘user:list’),有点麻烦

package com.zzhua.blog.config.security.auth;import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;import java.io.Serializable;// GlobalMethodSecurityConfiguration 在 afterSingletonsInstantiated 方法中,// 会去容器中寻找 PermissionEvaluator 的bean, 设置到 defaultMethodExpressionHandler 中,// 并且定义了一个 PreInvocationAuthorizationAdvice 的bean, 将刚刚的设置到 defaultMethodExpressionHandler 设置给了这个Advice,//// GlobalMethodSecurityConfiguration 并且定义了aop中的 methodSecurityInterceptor(),会去创建访问决策管理器,// 访问决策管理器会去添加投票器,里面会创建一个 PreInvocationAuthorizationAdviceVoter, 里面会传入上面定义的Advice,//// 所以接下来的流程看这个拦截器就行了,同时,也离不开 MethodSecurityMetadataSourceAdvisor 切面的支持 因此,方法鉴权就是基于Aop的实现,// 用法参考:SpringBoot 整合SpringSecurity示例实现前后分离权限注解+JWT登录认证-https://juejin.cn/post/6844903974546456590#heading-4
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {@Overridepublic boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {return false;}@Overridepublic boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {return false;}
}

自定义权限表达式

(也可以采用若依的方法,自定义权限表达式,其实就是利用了el表达式,但是通过自定义权限表达式的过程,可以更加清楚security处理方法注解权限时的整个处理过程,我们也可以在这里扩展一些权限通配符匹配的功能)

SysMethodSecurityExpressionHandler

可参考:如何在 Spring Security 中自定义权限表达式

源码流程

此handler 将会被注入到 GlobalMethodSecurityConfiguration#setMethodSecurityExpressionHandler 作为 handler

GlobalMethodSecurityConfiguration 定义了一个 PreInvocationAuthorizationAdvice 的bean, 获取并设置了上面定义的 handler

GlobalMethodSecurityConfiguration 并且定义了aop中的 methodSecurityInterceptor()拦截器,会去创建访问决策管理器

访问决策管理器会去添加投票器(当然,不止这一种投票器),会创建一个 PreInvocationAuthorizationAdviceVoter, 里面会传入上面定义的Advice,

@EnableWebSecurity引入了一个 MethodSecurityMetadataSourceAdvisorRegistrar ,
它创建了 MethodSecurityMetadataSourceAdvisor 切面, 并且指定了上面的拦截器名字作为构造参数, 使用 MethodSecurityMetadataSource 的实现(实现也有多种,通过组合的方式), 确定需要切入的bean(后面从方法中提取权限表达式,也是交给这个来实现)

所以后面的流程就是:

  • 当一个请求来到切入的方法,就会被拦截器处理, MethodSecurityInterceptor 拦截器 会拿到 AOP里面的 MethodInvocation,
  • 然后它会根据方法中的注解, 提取出所需权限, 交给访问决策管理器, 访问决策管理器 再交给 投票器,
  • 因此, 上面创建的投票器 又会交给 advice, advice又交给handler处理, 也就是下面定义的这个handler处理,
  • handler再利用el表达式计算, el会需要一个rootObject, 具体方法可以定义在rootObject里面, 只需要返回布尔值即可
package com.zzhua.blog.config.security.auth;import org.aopalliance.intercept.MethodInvocation;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;/*可参考:如何在 Spring Security 中自定义权限表达式-https://juejin.cn/post/7119086250610409508此handler 将会被注入到 GlobalMethodSecurityConfiguration#setMethodSecurityExpressionHandler 作为 handlerGlobalMethodSecurityConfiguration 定义了一个 PreInvocationAuthorizationAdvice 的bean, 获取并设置了上面定义的 handlerGlobalMethodSecurityConfiguration 并且定义了aop中的 methodSecurityInterceptor()拦截器,会去创建访问决策管理器访问决策管理器会去添加投票器(当然,不止这一种投票器),会创建一个 PreInvocationAuthorizationAdviceVoter, 里面会传入上面定义的Advice,@EnableWebSecurity引入了一个 MethodSecurityMetadataSourceAdvisorRegistrar ,它创建了 MethodSecurityMetadataSourceAdvisor 切面, 并且指定了上面的拦截器名字作为构造参数,使用 MethodSecurityMetadataSource 的实现(实现也有多种,通过组合的方式), 确定需要切入的bean(后面从方法中提取权限表达式,也是交给这个来实现)所以后面的流程就是:当一个请求来到切入的方法,就会被拦截器处理, MethodSecurityInterceptor 拦截器 会拿到 AOP里面的 MethodInvocation,然后它会根据方法中的注解, 提取出所需权限, 交给访问决策管理器, 访问决策管理器 再交给 投票器,因此, 上面创建的投票器 又会交给 advice, advice又交给handler处理, 也就是下面定义的这个handler处理,handler再利用el表达式计算, el会需要一个rootObject, 具体方法可以定义在rootObject里面, 只需要返回布尔值即可
*/
@Component
public class SysMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler {@Overrideprotected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,MethodInvocation invocation) {// 换成自己的实现,其它的都照抄源码里面的(下面又多了可以很多自定义的东西了)SysMethodSecurityExpressionRoot root = new SysMethodSecurityExpressionRoot(authentication);root.setThis(invocation.getThis());root.setPermissionEvaluator(getPermissionEvaluator());root.setTrustResolver(new AuthenticationTrustResolverImpl());root.setRoleHierarchy(getRoleHierarchy());// root.setDefaultRolePrefix("ROLE_");return root;}}

SysMethodSecurityExpressionRoot

package com.zzhua.blog.config.security.auth;import com.zzhua.blog.config.constant.SysConstants;
import com.zzhua.blog.config.security.UserDetailDTO;
import com.zzhua.blog.util.SecurityUtil;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;class SysMethodSecurityExpressionRootextends SecurityExpressionRootimplements MethodSecurityExpressionOperations {private Object filterObject;private Object returnObject;private Object target;SysMethodSecurityExpressionRoot(Authentication a) {super(a);}/* 自定义鉴权方法 */public boolean isAuth(String permission) {UserDetailDTO userDetailDTO = SecurityUtil.getPrincipal();if (SysConstants.IS_ADMIN.equals(userDetailDTO.getIsAdmin())) {return true;} else {List<String> authories = getAuthories();for (String authory : authories) {if (Objects.equals(authory, permission)) {return true;}}}return false;}private List<String> getAuthories() {Collection<? extends GrantedAuthority> authorities = getAuthentication().getAuthorities();List<String> authoritys = authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());return authoritys;}public void setFilterObject(Object filterObject) {this.filterObject = filterObject;}public Object getFilterObject() {return filterObject;}public void setReturnObject(Object returnObject) {this.returnObject = returnObject;}public Object getReturnObject() {return returnObject;}void setThis(Object target) {this.target = target;}public Object getThis() {return target;}
}

相关文章:

Security方法注解权限控制过程及自定义权限表达式

文章目录 使用内置的权限表达式PreAuthorizePermissionEvaluator 自定义权限表达式SysMethodSecurityExpressionHandler源码流程 SysMethodSecurityExpressionRoot 使用内置的权限表达式 PreAuthorize 这个用来判断超级管理员的话&#xff0c;还得在表达式上加上或 Permissi…...

vue 省市县三级联动

1、 <template><div>所在省<el-select popper-class"eloption" :popper-append-to-body"true"change"getShiList(obj.province)" v-model"obj.province" placeholder"请选择所在省" clearableclear"re…...

ChatGPT实现编程语言转换

编程语言转换 对于程序员来说&#xff0c;往往有一类工作&#xff0c;是需要将一部分业务逻辑实现从服务端转移到客户端&#xff0c;或者从客户端转移到服务端。这类工作&#xff0c;通常需要将一种编程语言的代码转换成另一种编程语言的代码&#xff0c;这就需要承担这项工作…...

浅拷贝和深拷贝

浅拷贝&#xff1a; 定义&#xff1a;浅拷贝&#xff08;Shallow Copy&#xff09;是一种简单的对象复制方式&#xff0c;将一个对象的数据成员直接复制给另一个对象&#xff08;通常是通过默认的复制构造函数或赋值运算符实现&#xff09;&#xff0c;这些数据成员可以是基本…...

进程地址空间与页表方面知识点(缺页中断及写时拷贝部分原理)

谢谢阅读&#xff0c;如有错误请大佬留言&#xff01;&#xff01; 目录 谢谢阅读&#xff0c;如有错误请大佬留言&#xff01;&#xff01; 抛出总结 开始介绍 发现问题 进程地址空间&#xff08;虚拟地址&#xff09; 页表 物理内存与进程地址空间映射 缺页中断基本…...

Photoshop如何使用滤镜之实例演示?

文章目录 0.引言1.将普通照片制作成油画效果2.使用液化滤镜修出完美身材3.用镜头光晕滤镜制作唯美的逆光人像4.用Camera Raw滤镜对偏色风景照进行调色 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对PS进行了学习&#xff0c;本文通过《Photoshop2021入门教程》及其…...

Flutter 组件抽取:日期(DatePicker)、时间(TimePicker)弹窗选择器【仿照】

简介 仿照《Flutter 仿ios自定义一个DatePicker》实行的日期弹窗选择器&#xff08;DatePicker&#xff09;、时间弹窗选择器&#xff08;TimePicker&#xff09; 效果 范例 class _TestPageState extends State<TestPage> {overridevoid initState() {super.initStat…...

基于opencv的YOLOV3对图片的目标检测

目录 1. 准备工作 2. utils 函数 2.1 plot_show 函数 2.2 get_prediction 函数 2.3 draw_bounding_box 绘制边界框函数...

Mermaid流程图

所有流程图都由节点&#xff0c;几何形状和边缘&#xff0c;箭头或线条组成。mermaid代码定义了这些节点和边缘的制作和交互方式。 它还可以容纳不同的箭头类型、多方向箭头以及与子图之间的链接。 1、流程图的方向 TB - 从上到下TD - 自上而下/与上到下相同BT - 从下到上RL -…...

国产!全志科技T507-H工业核心板( 4核ARM Cortex-A5)规格书

1核心板简介 创龙科技 SOM-TLT507 是一款基于全志科技 T507-H 处理器设计的 4 核 ARM Cortex-A 53 全国产工业核心板,主频高达 1.416GHz 。核心板 CPU 、ROM 、RAM、电源、晶振等所有元器件均采用国产工业级方案,国产化率 100%。 核心板通过邮票孔连接方式引出 MIPI CSI 、…...

java小记 2023-05-05

public class Test {/*** 谓类的方法就是指类中用static 修饰的方法&#xff08;非static 为实例方法&#xff09;&#xff0c;比如main 方法&#xff0c;那么可以以main* 方法为例&#xff0c;可直接调用其他类方法&#xff0c;必须通过实例调用实例方法&#xff0c;this 关键…...

CentOS安装Nginx

准备工作 在安装Nginx之前&#xff0c;我们需要进行一些准备工作&#xff1a; 确认系统是否已经安装了Nginx。如果已经安装了&#xff0c;需要卸载掉旧版本。安装EPEL源&#xff0c;以获取Nginx的软件包。安装必要的依赖软件包。 卸载旧版Nginx 如果已经安装了旧版本的Ngin…...

CSS布局基础(CSS书写顺序 导航栏写法 常见问题)

CSS布局基础&#xff08;CSS书写顺序 & 导航栏写法&#xff09; CSS布局基础&#xff08;CSS书写顺序&#xff09;导航栏写法PC端网页开发一般步骤容易出问题的点 CSS布局基础&#xff08;CSS书写顺序&#xff09; 布局定位属性自身属性&#xff08;宽高&#xff0c;边框&…...

打造卓越 QML 层级设计:从入门到精通

目录标题 引言&#xff1a;QML 层级设计的重要性1.1 什么是 QML1.2 层级设计的核心理念1.3 实际应用案例 QML 基础知识2.1 语言概述2.2 基本元素2.3 属性和信号 设计原则与规范3.1 命名规范3.1.1 标识符命名3.1.2 文件命名3.1.3 文件夹命名 3.2 代码风格3.2.1 缩进与空格3.2.2 …...

shell流程控制之条件判断练习

1、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查一次磁盘剩余空间。​ 因为如果磁盘剩余空间小于20G需要报警发送邮件给管理员&#xff0c;所以需要对管理员的邮箱进行设置 &#xff08;1&#xff09;首先…...

linux中TF启动卡制作:磁盘分区文件同步

文章目录 前言&#xff1a;1. 连接TF卡2. 磁盘卸载载与分区2.1 磁盘卸载2.2 创建第一个分区2.3 创建第二个分区 3. 磁盘格式化4. 文件同步5. 检查与BOOT分区启动文件拷贝总结&#xff1a; 前言&#xff1a; TF卡在linux环境下配置好相关软件后&#xff0c;把配置好的系统以及软…...

【操作系统OS】学习笔记:第一章 操作系统基础【哈工大李治军老师】

基于本人观看学习 哈工大李治军老师主讲的操作系统课程 所做的笔记&#xff0c;仅进行交流分享。 特此鸣谢李治军老师&#xff0c;操作系统的神作&#xff01; 如果本篇笔记帮助到了你&#xff0c;还请点赞 关注 支持一下 ♡>&#x16966;<)!! 主页专栏有更多&#xff0…...

Linux C/C++ 网络编程中地址格式转换(inet_pton和inet_ntop函数)

网络编程中地址格式转换&#xff08;inet_pton和inet_ntop函数&#xff09; 地址格式转换 #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h>int inet_pton(int af , const char * src ,void * dst);&#xff08;1&#xf…...

庖丁解牛函数知识---C语言《2》

目录 前言&#xff1a; 1.嵌套调用函数 2.链式访问 3.函数的声明与定义 4.*递归 5.递归与非递归 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础&#xff0c;C生万物&#xff01; 开始我们的C语言之旅吧…...

Git 使用教程:最详细、最正宗手把手教学(万字长文)

目录 一&#xff1a;Git二&#xff1a;SVN与Git的的区别三、安装Git四&#xff1a;常规操作五&#xff1a;远程仓库六&#xff1a;创建与合并分支七&#xff1a;bug分支八&#xff1a;多人协作九&#xff1a;git可视化工具 Git Git 是一种分布式版本控制系统&#xff0c;用于…...

AI时代当程序员?2026年转行IT的“新活法”

早知道AI会让程序员干这个&#xff0c;当年说啥也不信 凌晨三点&#xff0c;老刘瞪着AI生成的2000行代码&#xff0c;这已经是他熬夜修复的第47个bug了。 AI一分钟写完的模块&#xff0c;他调了三天。最绝的是——每修好一个bug&#xff0c;AI都能“贴心”地再送出三个新bug作为…...

Onekey:Steam游戏清单管理的自动化解决方案 | 玩家与开发者必备工具

Onekey&#xff1a;Steam游戏清单管理的自动化解决方案 | 玩家与开发者必备工具 【免费下载链接】Onekey Onekey Steam Depot Manifest Downloader 项目地址: https://gitcode.com/gh_mirrors/one/Onekey 当独立游戏开发者小林第三次因为手动复制Steam App ID出错而导致…...

建行江门市分行:银发关爱在行动 暖心服务送到家

服务无边界。近日&#xff0c;建行广东江门分行辖内多家网点接连上演暖心一幕&#xff0c;员工们主动跨出柜台&#xff0c;将金融服务送到客户家中、病房前&#xff0c;用一次次“特事特办”的上门服务&#xff0c;化解客户的“燃眉之急”&#xff0c;生动诠释了“以客户为中心…...

如何用RSPrompter提升遥感图像分割效果?基于SAM的实战技巧分享

如何用RSPrompter提升遥感图像分割效果&#xff1f;基于SAM的实战技巧分享 遥感图像分割一直是计算机视觉领域的难点之一。传统方法往往需要大量标注数据&#xff0c;而标注成本高昂&#xff0c;尤其是对于高分辨率遥感影像。2023年Meta发布的Segment Anything Model(SAM)展现了…...

如何快速将Blender模型导入Unreal Engine?免费Datasmith插件完整指南

如何快速将Blender模型导入Unreal Engine&#xff1f;免费Datasmith插件完整指南 【免费下载链接】bl_datasmith Blender addon to export UE4 Datasmith format 项目地址: https://gitcode.com/gh_mirrors/bl/bl_datasmith Blender Datasmith Export是一款开源免费的Bl…...

ConcurrentHashMap讲解

在 Java 并发编程中&#xff0c;ConcurrentHashMap 是高频使用的线程安全 Map 实现&#xff0c;也是面试中几乎必问的核心知识点。它完美解决了 HashMap 线程不安全、Hashtable 性能极差的痛点&#xff0c;在高并发场景下实现了安全与性能的平衡。本文将从设计背景、JDK1.7/JDK…...

哔哩哔哩第三方开放平台软件bilipai7.0.2

bilipai是一款面向B站内容爱好者的第三方安卓客户端&#xff0c;它有着清新灵动的界面风格和流畅自然的操作体验&#xff0c;能完整同步B站的各类视频资源&#xff0c;包括番剧、动画、知识科普、生活分享等内容类别&#xff0c;用户登录账号后&#xff0c;还可以实时同步自己的…...

专业流媒体视频下载工具技术解析与使用指南

专业流媒体视频下载工具技术解析与使用指南 价值主张&#xff1a;高效解决流媒体内容本地化需求 在数字内容消费日益普及的今天&#xff0c;用户对在线视频资源的本地保存需求持续增长。m3u8-downloader作为一款专业的流媒体下载工具&#xff0c;专注于解决m3u8格式视频的高效…...

当分包时,主包里有未被引用的文件,小程序预览【代码质量】显示包体积过大,不影响发布

1.项目加入分包后预览时显示主包体积超出&#xff1f;排查分包没问题&#xff0c;外部库方法也不会占很多空间2.代码依赖分析【显示 - 主包体积正常】主包实际体积&#xff08;768KB&#xff09;明明远小于 2MB 上限&#xff0c;但工具却提示「主包尺寸应小于 1.5M」且未通过。…...

公开信息整理|2026年3月26日:科学进展、词元活动、食品安全、护理保险与部分国际动态速览

&#x1f525;个人主页&#xff1a;杨利杰YJlio❄️个人专栏&#xff1a;《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》 《Python》 《Kali Linux》 《那些年未解决的Windows疑难杂症》&#x1f31f; 让复杂的事情更…...