自定义注解+拦截器/AOP切面 实现权限管理

news2024/12/28 3:03:58

一、通过拦截器实现

1 权限表

为了方便,我直接用的现成的权限表,这是表结构
在这里插入图片描述

2 自定义注解

首先,创建一个自定义注解,用于controller层的方法或类上

// @Target表示该注解可以用在方法和类上
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiPermission {

    PermissionEnum permission();

}

3 权限枚举类

PermissionEnum枚举内是权限枚举,值对应数据表中 api_permission 字段,后期会通过这个来校验权限

@Getter
public enum PermissionEnum {

    DEVICELIST_A("north:device:list"),
    DEVICEINFO_A("north:device:info"),
    DEVICEEXTEND_A("north:device:info:extend"),
    DEVICEHISTORICALDATA_A("north:device:historicalData"),
    DEVICESTATUS_A("north:device:status")
    ;

    private String value;

    PermissionEnum(String value) {
        this.value = value;
    }

}

4 拦截器

最重要的就是拦截器了,通过拦截器获取方法或类上的注解信息,然后比对权限表,判断是否拥有权限

@Component
@Slf4j
public class PermissionInterceptor implements HandlerInterceptor {

    @Autowired
    INorthAppApiService iNorthAppApiService;

    // 前置处理器
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod) handler;
            ApiPermission methodAnnotation = method.getMethodAnnotation(ApiPermission.class);
            //获取方法上的注解
            if (methodAnnotation == null) {
                System.out.println("内部错误");
                return false;
            }
            String appId = request.getParameter("appId");
            List<NorthAppApi> northAppApiList = iNorthAppApiService.getInfo(appId);
            boolean perBools = false;
            for (NorthAppApi northAppApi : northAppApiList) {
                if(northAppApi.getApiPermission().equals(methodAnnotation.permission().getValue())) {
                    perBools = true;
                }
            }
            if(!perBools) {
                System.out.println("无权限");
                return false;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

5 WebMvcConfig

别忘了将拦截器注册,不然拦截器不会生效

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private PermissionInterceptor permissionInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器
        registry.addInterceptor(permissionInterceptor).addPathPatterns("/**");
    }
}

6 使用

最后在controller层使用自己的自定义注解,在这里要注意,要使用@RequestMapping,不然会获取不到注解信息,但是我同事使用Post又可以获取,我也不知道为什么,有知道的可以评论告知

@RestController
@RequestMapping("/device")
public class DeviceController {

    @Autowired
    private DeviceService deviceService;

    // POSTMapping不行
    @ApiPermission(permission = PermissionEnum.DEVICELIST_A)
    @RequestMapping(value = "/list" )
    @ResponseBody
    public List<DeviceInfo> list(String appId) {
        System.out.println(deviceService.list());
        return null;
    }

    @ApiPermission(permission = PermissionEnum.DEVICEINFO_A)
    @RequestMapping(value = "/info" )
    @ResponseBody
    public List<DeviceInfo> info(String appId) {
        System.out.println(deviceService.list());
        return null;
    }
}

当我访问:http://localhost:9999/device/list?appId=dididache时,就可以通过权限返回数据,因为/device/list这个接口中写了我的自定义注解,传的appId可以查到该应用下拥有自定义注解中的权限记录,所以放行

如果我访问:http://localhost:9999/device/info?appId=dididache,我事先把数据表中第四条记录删了,因此权限表中 appId为dididache 的应用就不存在这个权限,因此无法放行

二、通过AOP实现

前面三个步骤跟上面的一样

4 切面类

@Aspect
@Component
public class InnerAuthAspect implements Ordered
{
    @Around("@annotation(innerAuth)")
    public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable
    {
        String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
        // 内部请求验证
        if (!StringUtils.equals(SecurityConstants.INNER, source))
        {
            throw new BusinessException("没有内部访问权限,不允许访问");
        }
        return point.proceed();
    }

    /**
     * 确保在权限认证aop执行前执行
     */
    @Override
    public int getOrder()
    {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }
}

这个切面类,环绕通知 @innerAuth注解,所以当执行带 @innerAuth 注解的方法或类时,就会执行这个通知逻辑,也就实现了代替拦截器实现权限校验的功能

然后可以跳过第五步,直接第六个步骤调用接口试一下,效果跟拦截器那个版本一样的

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

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

相关文章

5.注释和文档

本文讲解 Java 中的注释以及文档 ~ 文章目录 1. 注释1.1 引言1.1.1 何为注释&#xff1f;1.1.2 注释有何用&#xff1f; 1.2 类注释1.2 方法注释 2. 文档 1. 注释 1.1 引言 1.1.1 何为注释&#xff1f; 在我看来&#xff0c;注释无非是对一行或多行代码作的解释罢了。它能让…

Java学习_day08_finalnativeabstract接口

文章目录 final关键字注意 native关键字abstract关键字抽象类定义继承 接口定义实现 final关键字 final关键字表示常量&#xff0c;其值在程序运行期间不会改变。 final用来修饰变量&#xff0c;可以是静态变量&#xff0c;也可以是成员变量&#xff0c;也可以是局部变量&…

连接图书馆wifi无法验证如何解决

我们去图书馆连接wifi&#xff0c;无法验证自己身份&#xff0c;怎么办&#xff1f; 一般是电脑怀疑是不安全&#xff0c;进行了拦截。 我们点击不安全 再点击 与此站点的连接不安全 &#xff0c; 了解详情就可以显示登陆界面了&#xff0c;

点击清空按钮表单数据不能清空

清空选项只能清空角色和状态的数据,无法清空用户名的数据, 经过排查后发现 username这个单词写错了,导致点击清空searchFormRef?.resetFields()不能清空用户名数据

算法之路(一)

&#x1f58a;作者 : D. Star. &#x1f4d8;专栏 :算法小能手 &#x1f606;今日分享 : 如何学习&#xff1f; 在学习的过程中&#xff0c;不仅要知道如何学习&#xff0c;还要知道避免学习的陷阱。1. 睡眠不足&#xff1b;2. 被动学习和重读&#xff1b;3. 强调标记或画线&am…

接口--抽象方法

回答问题&#xff1a; 1.接口是什么&#xff1f; 2.接口中可以包含什么内容&#xff1f; 3.如何定义接口格式&#xff1f; 4.接口定义抽象方法格式&#xff1f; Code //接口是公共规范标准&#xff0c;类似于“模具” //如何定义接口格式&#xff1f;/** public interface 接…

【Qt之QVariant】使用

介绍 QVariant类类似于最常见的Qt数据类型的联合。由于C禁止联合类型包括具有非默认构造函数或析构函数的类型&#xff0c;大多数有趣的Qt类不能在联合中使用。如果没有QVariant&#xff0c;则QObject::property()和数据库操作等将会受到影响。 QVariant对象同时持有一个单一…

View 自定义 - 路径 Path

参考文章 一、概念 用于描述顺序 & 区域&#xff0c;单使用无法产生效果。 图形绘制的本质是先画点再将点连接起来&#xff0c;所以点与点之间是存在一个先后顺序的。图形的方向影响的是&#xff1a;添加图形时确定闭合顺序(各个点的记录顺序)、图形的渲染结果(是判断图形…

ArcGIS进阶:水源涵养功能分级评价操作

首先抛出水源涵养重要性评价的公式&#xff1a;水源涵养量降雨量-蒸散发量-地表径流量&#xff0c;其中地表径流量降雨量*平均地表径流系数 声明&#xff1a;以下数据来源于来自于牛强老师书籍&#xff08;城乡规划GIS技术&#xff09;。 以下给出重要性评价阈值表&#xff1…

『MySQL快速上手』-⑥-表的约束

文章目录 1.空属性2.默认值3.列描述4.zerofill5.主键6.自增长7.唯一键8.外键9.综合案例 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。 1.空…

高校为什么需要企业数据库?

随着信息化数字化的发展&#xff0c;企业数据库已经成为高校不可或缺的一部分。企业数据库一般整合了多维度企业数据信息。比如&#xff0c;艾思依托丰富的数据沉淀和领先的模型算法&#xff0c;打造“1N”产业大数据平台&#xff0c;包含“1个企业数据中心”一一涵盖全国2.4亿…

计算机提示找不到concrt140.dll怎么办,分享4个有效的修复方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示或者系统崩溃的情况。其中&#xff0c;concrt140.dll是一个常见的错误提示&#xff0c;这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题&#xff0c;我们需要采取一些修复措施。本文将介绍4个修复conc…

基于显著性的无人机多光谱图像语义杂草检测与分类

Saliency-Based Semantic Weeds Detection and Classification Using UAV Multispectral Imaging(2023&#xff09; 摘要1、介绍2、相关工作2.1 监督学习2.2 半监督学习2.3 无监督学习 3、方法3.1 贡献3.2 PC/BC-DIM NEURAL NETWORK&#xff08;预测编码/有偏竞争-分裂输入调制…

20个Python实用小技巧!来自十年老程序员的推荐~

文章目录 1.用itertools排列2.单行条件表达式3. 反转字符串4. 使用 Assert 处理异常5. 对多个输入使用拆分6. 用 zip() 转置矩阵7. 资源上下文管理器8. 下划线作为分隔符9. 尝试 f 字符串格式10.用这个技巧交换整数11. 使用 lambda 代替函数12.多次打印无循环13. 将字符串解包为…

基于机器学习的 ICU 脑血管疾病死亡风险智能预测系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 Wechat / QQ 名片 :) 1. 项目简介 重症患者或重大手术后的患者在重症监护室&#xff08;ICU&#xff09;内通过多种生命支持系统以维持生理功能。患者在ICU 内会被频繁持续的记录生命体征和实验室测量等多种数据。由于高频…

电大搜题——搜索难题

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 广东开放大学是一所素有口碑的知名学府&#xff0c;一直致力于为广大学员提供优质的教育资源和学习支持。随着科技的不断发展&#xff0c;电子学习成为了现代学习的主要方式之一。为了更好地满足学员的学习…

Django(一、简介,安装与使用)

文章目录 一、Django引入1.web应用程序什么是web&#xff1f;web引用程序的优点web应用程序的缺点什么是web框架 2.纯手写web框架1.web框架的本质2.HTTP协议的特性&#xff1a;3.编写基于wsgire模块搭建web框架代码封装优化代码封装 二、Django框架的学习1.Python中的主流框架2…

Kubernetes实战(四)-部署docker harbor私有仓库

1 Docker原生私有仓库Registry 1.1 原生私有仓库Registry概述 Docker的仓库主要分两类&#xff1a; 私有仓库公有仓库 共有仓库只要在官方注册用户&#xff0c;登录即可使用。但对于仓库的使用&#xff0c;企业还是会有自己的专属镜像&#xff0c;所以私有库的搭建也是很有…

基于SSM的婚恋网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

前端常用的开发工具有哪些?

目录 内置管理系统的通用场景 前后端代码生成器 权限管控 开放源码 运行性能 主流数据库 写在最后 目前使用的是JNPF框架。 前端采用Vue.js&#xff0c;这是一种流行的前端JavaScript框架&#xff0c;用于构建用户界面。Vue.js具有轻量级、可扩展性强和生态系统丰富等特点&…