Spring AOP 基于注解实现用户权限校验

主要注解

@interface:继承了 Annotation 接口的自定义注解,定义注释类型。

@Target:表示这个注解可以应用的地方,此处做权限校验是用在方法上的,所以此处的值为                          @Target(ElementType.METHOD)

@Retention:表示这个注解的保留策略,此处定义为 @Retention(RetentionPolicy.RUNTIME)

@Aspect:AOP依赖中的类,表示这个类是一个 Aspect,当应用程序中的其他组件和这个类中的方法相匹配时,spring 将自动执行这个方法,实现横切关注点的处理,此处横向关注点就是权限校验。

步骤

1. 引入依赖

引入 spring data starter AOP 依赖,版本对应项目的springboot 版本:Maven Repository: org.springframework.boot » spring-boot-starter-aop (mvnrepository.com)

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.7.2</version>
</dependency>

2. 编写 身份接口注解

这个注解的主要用途是用于身份验证,确保用户具有适当的权限来执行特定的操作。

/**
 * 用户权限接口
 * 包含用户角色
 * target注解表示该注解可以用于方法上
 * retention注解表示该注解在运行时有效
 */

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
    /**
     * 用户有的身份,只要有身份就是true
     *
     */
    String[] anyRoles() default "";
    /**
     * 用户必须有的身份,比如会员,管理员
     */
    String mustRole() default "";

}

 3. 编写 AOP 切面类

/**
 * 权限校验拦截
 */
@Aspect
@Component
public class AuthInterceptor {
    /**
     * 用户登录态键
     */
    private String USER_LOGIN_STATE = "userLoginState";
    @Resource
    private UserService userService;

    @Around("@annotation(authCheck)")
    public Object authCheck(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        //先获取当前用户登录态
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        //获取当前用户信息
        Object attribute = request.getSession().getAttribute(USER_LOGIN_STATE);
        User user=(User) attribute;
        if(user==null){
            return -1;
        }
        //获取用户权限
        String userRole = user.getUserRole();
        //获取用户角色列表
        String mustRole = authCheck.mustRole();
        List<String> anyRoles = Arrays.stream(authCheck.anyRoles()).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        //判断当前用户权限是否在用户角色列表中
        if(CollectionUtils.isNotEmpty(anyRoles)){
            if (!anyRoles.contains(userRole)){
                System.out.println("当前用户为权限不足,无法访问该接口");
                return -1;
            }
        }
        //判断当前用户权限是否在必须权限中
        if(StringUtils.isNotBlank(mustRole)){
            if(!mustRole.equals(userRole)){
                System.out.println("当前用户为普通用户,无法访问该接口");
                return -1;
            }
        };
        //检验完毕,执行后续方法。跳出切面
        return joinPoint.proceed();
    }

}

 

4.测试

在数据库直接添加一条数据

测试 mustRole 为 普通用户

在需要校验权限的接口添加注解。

    @AuthCheck(mustRole = "user")
    @PostMapping("/test")
    public void test(String string ){
        System.out.println("holleworld:"+ string);

    }

当权限校验通过就会输出 helloworld,失败就输出校验失败。

使用 swagger API 文档进行测试

测试 mustRole 为管理员

    @AuthCheck(mustRole = "admin")
    @PostMapping("/test")
    public void test(String string ){
        System.out.println("holleworld:"+ string);

    }

 

校验通过。

测试 anyRole 不包含

@AuthCheck(anyRoles = {"user","vip"})
    @PostMapping("/test")
    public void test(String string ){
        System.out.println("holleworld:"+ string);
    }
}

校验不通过。

测试 anyRole 包含

@AuthCheck(anyRoles = {"user","vip","admin"})
    @PostMapping("/test")
    public void test(String string ){
        System.out.println("holleworld:"+ string);
    }

校验通过。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【docker 如何自定义镜像】

查看容器列表 首先是查看容器&#xff1a;在命令台中键入 docker ps -a 命令&#xff0c;得到如下界面。 从容器创建一个新镜像 接着&#xff0c;dockers commit 容器名 要保存成的镜像名&#xff1a;版本名&#xff08;若没有 &#xff1a;版本名 则直接默认为latest&#x…

【CVPR2021】LoFTR:基于Transformers的无探测器的局部特征匹配方法

LoFTR&#xff1a;基于Transformers的局部检测器 0. 摘要 我们提出了一种新的局部图像特征匹配方法。我们建议先在粗略级别建立像素级密集匹配&#xff0c;然后再在精细级别细化良好匹配&#xff0c;而不是按顺序进行图像特征检测、描述和匹配。与使用成本体积搜索对应关系的密…

动手学深度学习(Pytorch版)代码实践 -深度学习基础-11暂退法Dropout

11暂退法Dropout #Dropout 是一种正则化技术&#xff0c;主要用于防止过拟合&#xff0c; #通过在训练过程中随机丢弃神经元来提高模型的泛化能力。 import torch from torch import nn from d2l import torch as d2l import liliPytorch as lpdef dropout_layer(X, dropout):…

安全宣传咨询日活动向媒体投稿记住这个投稿好方法

在信息爆炸的时代,作为单位的信息宣传员,我肩负着将每一次重要活动,特别是像“安全宣传咨询日”这样的公益活动,有效传达给公众的重任。这份工作看似简单,实则充满了挑战,尤其是在我初涉此领域时,那段曲折而又难忘的投稿经历,至今记忆犹新。 初探投稿之海,遭遇重重困难 起初,我…

这些数据可被Modbus采集,你还不知道???

为什么要用Modbus采集模块 Modbus采集模块之所以被广泛使用&#xff0c;是因为它提供了标准化的通信协议&#xff0c;确保了不同设备间的兼容性。它支持多种通信方式&#xff0c;易于实现&#xff0c;并且能够适应不同的网络环境。Modbus模块能够收集和传输各种工业数据&#x…

【产品经理】订单处理6-审单方案

电商系统中订单管理员会对特殊类型的订单进行审核&#xff0c;普通订单则自动审核&#xff0c;本节讲述自动审单方案、手动审单以及加急审单。 一、自动审单 自动审单方案可按照方案形式制定&#xff0c;可一次性制定多套审单方案。 1. 审单通过条件有 执行店铺&#xff…

大模型的分类:探索多样化的人工智能模型

随着人工智能技术的飞速发展&#xff0c;大型预训练模型&#xff08;以下简称“大模型”&#xff09;已经在自然语言处理、计算机视觉、语音识别等多个领域取得了显著的成果。这些模型通过在海量数据上进行预训练&#xff0c;能够捕捉到丰富的特征信息&#xff0c;为各种下游任…

Linux操作系统学习:day03

内容来自&#xff1a;Linux介绍 视频推荐&#xff1a;[Linux基础入门教程-linux命令-vim-gcc/g -动态库/静态库 -makefile-gdb调试]( 目录 day0317、创建删除目录创建目录删除目录 18、文件的拷贝19、mv 命令20、查看文件内容的相关命令21、给文件创建软连接或硬链接 day03 …

MFC绘制哆啦A梦

OnPaint绘制代码 CPaintDC dc(this); // 用于绘画的设备上下文CRect rc;GetWindowRect(rc);int cxClient rc.Width();int cyClient rc.Height();// 辅助线HPEN hPen CreatePen(PS_DOT, 1, RGB(192, 192, 192));HPEN hOldPen (HPEN)SelectObject(dc, hPen);MoveToEx(dc, cxC…

使用Vue中的<TransitionGroup/>进入动画不生效不显示问题

Vue中有两个过渡动画组件分别是&#xff1a;<TransitionGroup/> <TransitionGroup/>进入动画不生效不显示问题 &#xff0c;在渲染列表上加上v-if&#xff0c;看代码&#xff0c;让他每次渲染都重新渲染 加上v-if即可 <template> <TransitionGroup nam…

Perforce静态代码分析专家解读MISRA C++:2023®新标准:如何安全、高效地使用基于范围的for循环,防范未定义行为

MISRA C&#xff1a;2023——MISRA C 标准的下一个版本来了&#xff01;为了帮助您了解 MISRA C&#xff1a;2023相比于之前版本的变化&#xff0c;我们将继续为您带来Perforce首席技术支持工程师Frank van den Beuken博士的博客系列&#xff0c;本期为第三篇。 在前两篇系列文…

和服务器建立联系——6.10山大软院项目实训1

下面介绍我如何在自己的项目中&#xff0c;根据aigc组的接口&#xff08;如下图&#xff09;&#xff0c;在Unity中和服务器建立联系并发出接受请求的&#xff1a; 这是一个通过HTTP POST方法调用的接口&#xff0c;需要发送JSON格式的数据。在Unity中实现这样的功能&#xff0…

文字炫酷祝福 含魔法代码

效果下图&#xff1a;&#xff08;可自定义显示内容&#xff09; 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…

SpringBoot + Maven 项目的创建

文章目录 1、Maven2、SpringBoot3、二者之间的联系4、项目的创建 在创建项目之前&#xff0c;肯定要知道他们之间的区别 1、Maven maven是一个跨平台的项目管理工具。它是Apache的一个开源项目&#xff0c;主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。 比如说…

QT day04

一、思维导图 二、登录界面优化 代码&#xff1a; 界面&#xff1a; *{background-color: rgb(255, 255, 255); }QFrame#frame{border-image: url(:/Logo/shanChuan.jpg);border-radius:15px; }#frame_2{background-color: rgba(110, 110, 110, 120);border-radius:15px; }Q…

线代的学习(矩阵)

1.矩阵的乘法 矩阵实现满足&#xff1a;内标相等 矩阵相乘之后的结果&#xff1a;前行后列 需要注意&#xff1a;1.矩阵的乘法不具有交换律&#xff1a;AB!BA 2.矩阵的乘法满足分配律&#xff1a;A(BC) AB AC 抽象逆矩阵求逆矩阵 方法1.凑定义法、 方法2.长除法 数字型矩阵…

一文弄懂 Python os.walk(),轻松搞定文件处理和目录遍历

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ Python os 模块的 walk() 方法以自顶向下或自底向上的方式遍历指定的目录树&#xff0c;从而显示目录树中的文件名。对于目录树中的每个目录&#xff0c;os.walk() 方法都会产生一个包含目录路径、当前…

vue3第四十节(pinia的用法注意事项解构store)

pinia 主要包括以下五部分&#xff0c;经常用到的是 store、state、getters、actions 以下使用说明&#xff0c;注意事项&#xff0c;仅限于 vue3 setup 语法糖中使用&#xff0c;若使用选项式 API 请直接查看官方文档&#xff1a; 一、前言&#xff1a; pinia 是为了探索 vu…

04-对原生app应用中的元素进行定位

本文介绍对于安卓原生app应用中的元素如何进行定位。 一、uiautomatorviewer uiautomatorviewer是Android-SDK自带的一个元素定位工具&#xff0c;非常简单好用&#xff0c;可以使用该工具查看app应用中的元素属性&#xff0c;帮助我们在代码中进行元素定位。 1&#xff09;使…

Win11版本21H2怎么升级为23H2?升级详细步骤在此!

在Win11电脑操作中&#xff0c;用户目前使用的版本是21H2&#xff0c;现在想体验23H2版本的先进功能&#xff0c;但不知道要怎么操作才能将系统版本升级为23H2&#xff1f;接下来小编给大家介绍详细的升级方法步骤&#xff0c;助力大家轻松完成系统版本升级操作。 方法一&#…