注解+AOP实现权限控制

news2025/3/16 18:15:05

注解与AOP实战:实现权限控制

在现代Java开发中,注解(Annotation)和面向切面编程(AOP)是两种强大的技术,它们能够帮助我们实现代码的解耦,提高代码的可读性和可维护性。本文将通过一个实际的例子,展示如何结合自定义注解和AOP来实现权限控制。

1. 什么是注解?

注解是Java提供的一种元数据机制,能够为代码添加额外的信息。注解本身不会影响代码的执行,但可以通过反射等机制在运行时读取这些信息,进而实现特定的功能。

1.1 自定义注解

以下是一个自定义注解 @AuthCheck 的示例,用于标记需要权限控制的方法:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) // 注解只能用于方法
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时保留
public @interface AuthCheck {
    String mustRole() default ""; // 必须具有的角色
}

在这个注解中,mustRole 属性用于指定调用该方法所需的角色。

2. 什么是AOP?

AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它允许我们将横切关注点(如日志记录、权限控制、事务管理等)从业务逻辑中分离出来。通过AOP,我们可以在不修改原有代码的情况下,动态地为方法添加额外的功能。

2.1 AOP的核心概念

  • 切面(Aspect):包含横切关注点的模块。
  • 连接点(Join Point):程序执行的某个点,例如方法调用。
  • 通知(Advice):在连接点上执行的动作,如前置通知、后置通知等。
  • 切入点(Pointcut):定义在哪些连接点上应用通知。

3. 实战:使用注解和AOP实现权限控制

3.1 定义权限控制注解

我们已经在前面定义了 @AuthCheck 注解,用于标记需要权限控制的方法。

3.2 实现权限拦截器

以下是一个基于Spring AOP的权限拦截器 AuthInterceptor,它会拦截带有 @AuthCheck 注解的方法,并根据注解中的角色要求进行权限校验:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Aspect // 标记为切面
@Component // 注册为Spring Bean
public class AuthInterceptor {

    @Resource
    private UserApplicationService userApplicationService;

    /**
     * 拦截带有 @AuthCheck 注解的方法
     *
     * @param joinPoint 切入点
     * @param authCheck 权限校验注解
     * @return 执行结果
     * @throws Throwable 异常
     */
    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        String mustRole = authCheck.mustRole(); // 获取注解中指定的角色
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

        // 获取当前登录用户
        User loginUser = userApplicationService.getLoginUser(request);
        UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole);

        // 如果不需要权限,直接放行
        if (mustRoleEnum == null) {
            return joinPoint.proceed();
        }

        // 检查用户角色
        UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
        if (userRoleEnum == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR); // 用户角色为空,抛出无权限异常
        }

        // 如果要求管理员权限,但用户不是管理员,抛出无权限异常
        if (UserRoleEnum.ADMIN.equals(mustRoleEnum) && !UserRoleEnum.ADMIN.equals(userRoleEnum)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }

        // 通过权限校验,放行
        return joinPoint.proceed();
    }
}

3.3 在业务方法中使用注解

以下是一个使用 @AuthCheck 注解的业务方法示例,只有管理员角色才能调用该方法:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR); // 参数校验
        }
        boolean b = userApplicationService.deleteUser(deleteRequest); // 删除用户
        return ResultUtils.success(b); // 返回结果
    }
}

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

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

相关文章

Java数据结构第二十三期:Map与Set的高效应用之道(二)

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、哈希表 1.1. 概念 1.2. 冲突 1.3. 避免冲突 1.4. 解决冲突 1.5. 实现 二、OJ练习 2.1. 只出现一次的数字 2.2. 随机链表的复制 2.3. 宝石与石头 一、哈希表 1.1. 概念 顺序结构以及平衡树中…

linux系统命令——权限

一、有哪些权限 读&#xff08;r&#xff09;——对应数字4 写&#xff08;w&#xff09;——对应数字2 执行&#xff08;x&#xff09;——对应数字1 二、权限及数字的对应 4对应r-- 2对应-w- 1对应--x 5对应r-x 6对应rw- 7对应rwx 三、文件的基本属性 如图&#…

PentestGPT 下载

PentestGPT 下载 PentestGPT 介绍 PentestGPT&#xff08;Penetration Testing GPT&#xff09;是一个基于大语言模型&#xff08;LLM&#xff09;的智能渗透测试助手。它结合了 ChatGPT&#xff08;或其他 GPT 模型&#xff09;与渗透测试工具&#xff0c;帮助安全研究人员自…

JVM 2015/3/15

定义&#xff1a;Java Virtual Machine -java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&#xff0c;到处运行 自动内存管理&#xff0c;垃圾回收 数组下标越界检测 多态 比较&#xff1a;jvm/jre/jdk 常见的JVM&…

sql靶场-时间盲注(第九、十关)保姆级教程

目录 时间盲注&#xff08;第九、十关&#xff09; 1.判断 2.确认时间盲注 2.手工尝试时间盲注 数据库名长度 数据库名字符 表数 表名长度 表名字符 字段数 字段名长度 字段名字符 4.脚本时间盲注注入 5.第十关 时间盲注&#xff08;第九、十关&#xff09; 1.判…

51c自动驾驶~合集54

我自己的原文哦~ https://blog.51cto.com/whaosoft/13517811 #Chameleon 快慢双系统&#xff01;清华&博世最新&#xff1a;无需训练即可解决复杂道路拓扑 在自动驾驶技术中&#xff0c;车道拓扑提取是实现无地图导航的核心任务之一。它要求系统不仅能检测出车道和交…

大模型推理:LM Studio在Mac上部署Deepseek-R1模型

LM Studio LM Studio是一款支持离线大模型部署的推理服务框架&#xff0c;提供了易用的大模型部署web框架&#xff0c;支持Linux、Mac、Windows等平台&#xff0c;并提供了OpenAI兼容的SDK接口&#xff0c;主要使用LLama.cpp和MLX推理后端&#xff0c;在Mac上部署时选择MLX推理…

扩散模型:AIGC领域的核心引擎,解锁图像生成新维度

一、扩散模型技术原理 扩散模型是一类生成模型&#xff0c;它运用了物理热力学中的扩散思想&#xff0c; 主要包括前向扩散和反向扩散两个过程。 1.1、生成模型 在深度学习中&#xff0c;生成模型的目标是根据给定的样本&#xff08;训练数据&#xff09; 生成新样本。首先给…

Java多线程与高并发专题——原子类和 volatile、synchronized 有什么异同?

原子类和 volatile异同 首先&#xff0c;通过我们对原子类和的了解&#xff0c;原子类和volatile 都能保证多线程环境下的数据可见性。在多线程程序中&#xff0c;每个线程都有自己的工作内存&#xff0c;当多个线程访问共享变量时&#xff0c;可能会出现一个线程修改了共享变…

【数据结构】数据结构,算法 概念

0.本篇问题&#xff1a; 数据、数据元素、数据对象、数据项之间的基本关系&#xff1f;ADT是什么&#xff1f;数据结构的三要素&#xff1f;数据的逻辑结构有哪些&#xff1f;数据的存储结构有哪些&#xff1f;算法的五个特征&#xff1f;O(1) O(logn) O(n^n) O(n) O(n^2…

总结 HTTP 协议的基本格式, 相关知识以及抓包工具fiddler的使用

目录 1 HTTP是什么 2 HTTP协议格式 3 HTTP请求(Request) 3.1 认识URL 3.2 方法 3.3 认识请求"报头"(header) 4 HTTP响应详解 4.1 认识"状态码"(statuscode) 4.2 认识响应"报头"(header) 4.3 认识响应"正⽂"(body) 5 通过f…

探索Maas平台与阿里 QWQ 技术:AI调参的魔法世界

摘要&#xff1a;本文介绍了蓝耘 Maas 平台在人工智能领域的表现及其核心优势&#xff0c;包括强大的模型支持、高效的资源调度和友好的操作界面。文章还探讨了蓝耘 Maas 平台与阿里 QWQ 技术的融合亮点及应用拓展实例&#xff0c;并提供了调参实战指南&#xff0c;最后对蓝耘 …

Linux第三次练习

1、创建根目录结构中的所有的普通文件 首先在根目录下面新创建一个test目录&#xff0c;然后将查找到的普通文件新建到test目录下 2、列出所有账号的账号名 3、将/etc/passwd中内容按照冒号隔开的第三个字符从大到小排序后输出所有内容 4、列出/etc/passwd中的第20行-25行内容…

软件测试知识总结

1、黑盒测试、白盒测试、灰盒测试 1.1 黑盒测试 黑盒测试又叫功能测试、数据驱动测试 或 基于需求规格说明书的功能测试。该类测试注重于测试软件的功能性需求。 采用这种测试方法&#xff0c;测试工程师把测试对象看作一个黑盒子&#xff0c;完全不考虑程序内部的逻辑结构和…

【HTML】三、表单与布局标签

文章目录 1、input1.1 input的占位文案1.2 单选框1.3 上传文件1.4 多选框 2、 下拉菜单3、文本域&#xff1a;多行输入4、label标签&#xff1a;说明与增大点击范围5、按钮与form表单6、无语义布局标签7、有语义的布局标签8、字符实体9、练习&#xff1a;注册页面 1、input in…

【结构设计】3D打印创想三维Ender 3 v2

【结构设计】3D打印创想三维Ender 3 v2 文章目录 前言一、Creality Slicer1.2.3打印参数设置二、配件更换1.捆扎绑扎线2.气动接头3D打印机配件插头3.3D打印机配件Ender3pro/V2喷头套件4.读卡器 TF卡5.micro sd卡 三、调平四、参考文章总结 前言 使用工具&#xff1a; 1.创想三…

UE小:UE5.5 PixelStreamingInfrastructure 使用时注意事项

1、鼠标默认显示 player.ts中的Config中添加HoveringMouse:true 然后运行typescript\package.json中的"build":npx webpack --config webpack.prod.js

Anaconda 入门指南

Anaconda 入门指南 一、下载安装 Anaconda 1、下载地址&#xff1a;Anaconda 推荐下载 python3 版本, 毕竟未来 python2 是要停止维护的。 2、安装 Anaconda 按照安装程序提示一步步安装就好了, 安装完成之后会多几个应用&#xff1a; Anaconda Navigtor &#xff1a;用于管…

web组态可视化编辑器

Web组态可视化编辑器是一种用于创建和配置工业自动化、物联网&#xff08;IoT&#xff09;和智能建筑等领域的图形化用户界面&#xff08;GUI&#xff09;的工具。它允许用户通过拖放组件、配置参数和连接数据源来设计和部署实时监控和控制界面。以下是一些常见的Web组态可视化…

CTA重建:脑血管重建,CT三维重建,三维建模 技术,实现

CTA&#xff08;CT血管造影&#xff09;是一种基于CT扫描的医学成像技术&#xff0c;主要用于血管系统的三维重建和可视化。脑血管重建是CTA的重要应用之一&#xff0c;能够帮助医生诊断脑血管疾病&#xff08;如动脉瘤、狭窄、畸形等&#xff09;。以下是实现CTA脑血管重建、C…