一文搞定登录权限验证,轻松掌握过滤器、拦截器与AOP

文章目录

  • 前言
  • 1. 过滤器(Filter)
    • 1.1 定义
    • 1.2 特点
    • 1.3 应用场景
    • 1.4 使用步骤
      • 1.4.1 自定义Filter
      • 1.4.2 编写配置类
  • 2.拦截器
    • 2.1 定义
    • 2.2 特点
    • 2.3应用场景
    • 2.4 使用步骤
      • 2.4.1 自定义拦截器
      • 2.4.2 注册拦截器
  • 3. AOP
    • 3.1 定义
    • 3.2 特点
    • 3.3 应用场景
    • 3.4 使用步骤
      • 3.4.1 自定义注解
      • 3.4.2 定义切面
      • 3.4.3 使用注解
  • 4. 总结
    • 4. 1 过滤器 vs 拦截器
    • 4.2 拦截器 vs AOP
    • 4.3 过滤器 vs AOP


前言

对于权限验证的方式,我们一般知道可以采用以下几种方式进行控制:

  1. 过滤器
  2. 拦截器
  3. AOP
  4. Spring Gateway
  5. SpringSecurity
  6. Shiro

对于一个简单的权限验证,也没有必要使用三方框架这么麻烦。这里我通过使用过滤器,拦截器、AOP来进行登录验证,来了解三者的区别。

1. 过滤器(Filter)

1.1 定义

过滤器是Servlet规范中定义的一种对象,用于在请求被处理之前或者响应被发送到客户端之前进行拦截和处理。

1.2 特点

  • 可以处理HTTP请求和响应,是Servlet规范的一部分,与特定的框架无关
  • 只能操作HttpServletRequest和HttpServletResponse对象,不能访问Spring容器中的Bean
  • 可以用于编码转换、字符集设置、日志记录、安全控制等。

1.3 应用场景

  • 访问控制(如身份验证、权限控制)
  • 日志记录和审计
  • 压缩响应数据
  • 图片水印处理等

跨站脚本攻击,SQL注入等,可以采取Filter的方式,Filter是拦截所有的请求,包扩静态资源。

1.4 使用步骤

1.4.1 自定义Filter

/**
 * <p>
 * 登录过滤器
 * </p>
 *
 * @author shiqi
 * @version 1.0.0
 * @createTime 2024-07-02
 */
public class LoginFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化过滤器
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse)  servletResponse;

        // 获取会话中的用户信息
        Object user = httpRequest.getSession().getAttribute("user");

        // 获取请求的URL
        String requestURI = httpRequest.getRequestURI();

        // 允许访问登录页面和静态资源
        if (user == null && !requestURI.endsWith("/login") && !requestURI.contains("/static/")) {
            // 用户未登录,且请求不是登录页面或静态资源,重定向到登录页面
            httpResponse.setContentType("application/json;charset=UTF-8");
            httpResponse.getWriter().write("{\"code\":401,\"msg\":\"未登录\"}");
            return ;
        }

        // 用户已登录或请求是登录页面,继续处理请求
        chain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        // 销毁过滤器
    }
}

1.4.2 编写配置类

/**
 * <p>
 * 配置过滤器的配置类。
 * </p>
 *
 * @author shiqi
 * @version 1.0.0
 * @createTime 2024-07-02
 */
@Configuration
public class FilterConfig {
    /**
     * 配置LoginFilter的注册bean。
     * 该方法创建一个FilterRegistrationBean实例,用于注册LoginFilter,并配置其拦截的URL模式。
     * @return FilterRegistrationBean<LoginFilter> 登录过滤器的注册bean,用于Spring Boot应用程序中。
     */
    @Bean
    public FilterRegistrationBean<LoginFilter> loginFilter() {
        FilterRegistrationBean<LoginFilter> registrationBean = new FilterRegistrationBean<>();

        // 设置LoginFilter实例
        registrationBean.setFilter(new LoginFilter());
        // 指定LoginFilter应拦截的所有URL模式
        registrationBean.addUrlPatterns("/*"); // 拦截所有请求

        return registrationBean;
    }
}

2.拦截器

2.1 定义

拦截器是Spring MVC框架提供的一种机制,用于在请求处理的各个阶段(如处理器执行之前、之后、视图渲染之前)进行预处理和后处理。

2.2 特点

  • 是Spring MVC框架的一部分,依赖于Spring容器。
  • 可以访问Spring容器中的Bean,对业务处理方法进行增强。
  • 主要用于业务处理的预处理和后处理,如日志记录、权限检查、事务管理等。

2.3应用场景

  • 登录验证和权限控制
  • 日志记录和性能监控
  • 事务管理和异常处理

2.4 使用步骤

2.4.1 自定义拦截器

/**
 * <p>
 * 登录拦截器
 * </p>
 *
 * @author shiqi
 * @version 1.0.0
 * @createTime 2024-07-02
 */
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前进行调用(Controller方法调用之前)
        // 返回true表示放行,返回false表示拦截
        Object user = request.getSession().getAttribute("user");
        if (user == null) {
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("未登录");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 请求处理之后调用,但在视图被渲染之前(Controller方法调用之后)
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 整个请求完成之后调用,用于清理资源等
    }
}

2.4.2 注册拦截器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 添加拦截器到拦截器注册表中。
     *
     * 本方法的目的是为了配置一个特定的拦截器,即LoginInterceptor,以拦截所有符合指定路径模式的请求。
     * 通过这种方式,可以对特定的URL路径进行额外的权限检查或逻辑处理,而不需要修改每个控制器或方法。
     *
     * @param registry 拦截器注册表,用于添加新的拦截器和配置它们的拦截规则。
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加LoginInterceptor拦截器,并指定它应该拦截所有以"/index/**"为路径模式的请求。
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/index/**");
    }
}

3. AOP

3.1 定义

面向切面编程是一种编程范式,用于通过定义横切关注点(如日志、事务、安全性)来减少代码重复性并增强模块化。

3.2 特点

  • 是一种横切关注点的编程思想,与具体框架(如Servlet或Spring MVC)无关。
  • 可以用于跨多个类和对象实现通用功能,如事务管理、日志记录、缓存等。
  • 基于代理机制实现,在运行时动态地将切面织入到程序流程中。

3.3 应用场景

  • 事务管理(如声明式事务)
  • 日志记录(如方法调用日志)
  • 安全控制(如权限检查)
  • 性能监控和缓存管理

3.4 使用步骤

3.4.1 自定义注解

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequirePermission {

    String[] roles() default {};
}

3.4.2 定义切面

@Aspect
@Component
public class LoginAspect{

    @Pointcut("@annotation(com.shiqi.securitydemo.aop.RequirePermission)")
    public void pointCut() {

    }

    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {

        // 执行目标方法
        // 获取方法签名
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        // 获取方法
        Method method = signature.getMethod();
        // 获取方法上的注解
        RequirePermission permission = method.getAnnotation(RequirePermission.class);
        String[] roles = permission.roles();
        if (roles.length > 0){
            // 验证权限
            for (String role : roles) {
                if(!role.equals("admin")){
                    // 抛出异常
                    return "权限不足";
                }

            }

        }


        return pjp.proceed();
    }
}

3.4.3 使用注解

@RestController
@RequestMapping
public class IndexController {


    @RequestMapping("/index")
    public String index() {
        return "index";
    }


    /**
     * 处理管理员相关的请求。
     *
     * 该方法映射到管理员界面的URL路径。只有具备管理员角色的用户才能访问该页面。
     * 通过返回字符串"admin",指示Spring MVC将请求重定向到名为"admin"的视图或页面。
     *
     * @return 表示管理员页面的字符串
     */
    @RequestMapping("/admin")
    @RequirePermission(roles = {"guest"})
    public String admin(){
        return "admin";
    }
}

4. 总结

对比及应用场景总结

4. 1 过滤器 vs 拦截器

  • 过滤器是Servlet规范的一部分,独立于具体框架,主要用于HTTP请求和响应的预处理和后处理,如字符编码、安全控制等。
  • 拦截器是Spring MVC框架的一部分,依赖于Spring容器,可以访问Spring管理的Bean,用于业务处理方法的预处理和后处理,如权限验证、事务管理等。

4.2 拦截器 vs AOP

  • 拦截器是针对特定的请求路径或者Controller进行拦截和增强,属于局部性的增强。
  • AOP是一种更为广泛的横切关注点的编程思想,可以跨多个类和对象实现通用功能的增强,如事务管理、日志记录等。

4.3 过滤器 vs AOP

  • 过滤器主要用于HTTP请求和响应的处理,功能较为局限,主要在Servlet规范中使用。
  • AOP能够更加灵活地实现横切关注点的编程,不限于HTTP请求,可以应用于各种业务逻辑中,实现功能的解耦和复用。

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

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

相关文章

C语言 | Leetcode C语言题解之第198题打家劫舍

题目&#xff1a; 题解&#xff1a; int rob(int* nums, int numsSize){// dp0: 不偷这个屋子能窃到的最高金额int dp0 0;// dp1: 偷这间屋子能窃到的最高金额int dp1 nums[0];for (int i 1; i < numsSize; i) {int dp0new fmax(dp0, dp1);int dp1new dp0 nums[i];dp…

前端知识点

HTML、CSS 相关 1、 BFC 1、BFC 是什么&#xff1f; BFC&#xff08;Block Formatting Context&#xff09; 格式化上下文&#xff1b; 指一个独立的渲染区域&#xff0c;或者说是一个隔离的独立容器&#xff1b;可以理解为一个独立的封闭空间。无论如何不会影响到它的外面 …

day09了 加油

浅拷贝 指向同一个地址空间 右边不可取地址 左边一定是到了具体的位置 右值引用std&#xff1a;&#xff1a; move 相信大家默认构造函数都没有问题&#xff0c;所以就不贴例子了 浅拷贝构造函数 只负责复制地址&#xff0c;而不是真的把完整的内存给它 #include <iostre…

【MySQL备份】Percona XtraBackup基础篇

目录 1.关于Percona XtraBackup 2. Percona XtraBackup有哪些特点&#xff1f; 3.安装Percona XtraBackup 3.1.环境信息 3.2.安装步骤 4. xtrabackup内部流程图 5.Percona XtraBackup基础语法 5.1.全量备份 5.2.增量备份 5.2.1.基于全量备份的增量备份 5.2.2.基于前…

超越所有SOTA达11%!媲美全监督方法 | UC伯克利开源UnSAM

文章链接&#xff1a;https://arxiv.org/pdf/2406.20081 github链接&#xff1a;https://github.com/frank-xwang/UnSAM SAM 代表了计算机视觉领域&#xff0c;特别是图像分割领域的重大进步。对于需要详细分析和理解复杂视觉场景(如自动驾驶、医学成像和环境监控)的应用特别有…

深入解读OkHttp3中的Request5

OkHttp 是由 Square 开发的一个高效的 HTTP 客户端库&#xff0c;广泛应用于 Android 开发中。作为资深安卓开发工程师&#xff0c;我们经常需要与网络通信打交道&#xff0c;而 OkHttp 提供了一个简洁而强大的 API 来处理这些通信。在这篇文章中&#xff0c;我们将深入探讨 Ok…

python自动化运维--DNS处理模块dnspython

1.dnspython介绍 dnspython是Pyhton实现的一个DNS工具包&#xff0c;他几乎支持所有的记录类型&#xff0c;可以用于查询、传输并动态更新ZONE信息&#xff0c;同事支持TSIG&#xff08;事物签名&#xff09;验证消息和EDNS0&#xff08;扩展DNS&#xff09;。在系统管理方面&a…

EVE-NG网络仿真平台搭建

现在目前实验都是使用华为的Ensp模拟器&#xff0c;但是有时候一些功能模拟器无法实现&#xff0c;要不就是使用真机进行实验&#xff0c;第二个就是换个支持相关命令的模拟器了&#xff0c;今天来简单学习下EVE-NG这个模拟器。 一、EVE-NG简介 EVE-NG&#xff08;Emulated Vir…

【深度学习】注意力机制

https://blog.csdn.net/weixin_43334693/article/details/130189238 https://blog.csdn.net/weixin_47936614/article/details/130466448 https://blog.csdn.net/qq_51320133/article/details/138305880 注意力机制&#xff1a;在处理信息的时候&#xff0c;会将注意力放在需要…

HarmonyOS开发实战:UDP通讯示例规范

1. UDP简介 UDP协议是传输层协议的一种&#xff0c;它不需要建立连接&#xff0c;是不可靠、无序的&#xff0c;相对于TCP协议报文更简单&#xff0c;在特定场景下有更高的数据传输效率&#xff0c;在现代的网络通讯中有广泛的应用&#xff0c;以最新的HTTP/3为例&#xff0c;…

2024年6月29日 (周六) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 喜马拉雅下载工具: 字面意思 《星刃》性感女主私密部位细节逼真 让玩家感到惊讶《星刃…

探索NVIDIA A100 显卡 如何手搓A100显卡

NVIDIA A100 显卡&#xff08;GPU&#xff09;是基于NVIDIA的Ampere架构设计的高性能计算和人工智能任务的处理器。 A100显卡主要由以下几种关键芯片和组件组成&#xff1a; 1. GPU芯片 NVIDIA GA100 GPU&#xff1a; 核心组件&#xff0c;是整个显卡的核心处理单元。GA100芯…

Ubuntu24.04 Isaacgym的安装

教程1 教程2 教程3 1.下载压缩包 link 2. 解压 tar -xvf IsaacGym_Preview_4_Package.tar.gz3. 从源码安装 Ubuntu24.04还需首先进入虚拟环境 python -m venv myenv # 创建虚拟环境&#xff0c;已有可跳过 source myenv/bin/activate # 激活虚拟环境python编译 cd isaa…

Python容器 之 字符串--字符串的常用操作方法

1.字符串查找方法 find() 说明&#xff1a;被查找字符是否存在于当前字符串中。 格式&#xff1a;字符串.find(被查找字符) 结果&#xff1a;如果存在则返回第一次出现 被查找字符位置的下标 如果不存在则返回 -1 需求&#xff1a; 1. 现有字符串数据: 我是中国人 2. 请设计程序…

Python 作业题1 (猜数字)

题目 你要根据线索猜出一个三位数。游戏会根据你的猜测给出以下提示之一&#xff1a;如果你猜对一位数字但数字位置不对&#xff0c;则会提示“Pico”&#xff1b;如果你同时猜对了一位数字及其位置&#xff0c;则会提示“Fermi”&#xff1b;如果你猜测的数字及其位置都不对&…

网络爬虫基础知识

文章目录 网络爬虫基础知识爬虫的定义爬虫的工作流程常用技术和工具爬虫的应用1. 抓取天气信息2. 抓取新闻标题3. 抓取股票价格4. 抓取商品价格5. 抓取博客文章标题 网络爬虫基础知识 爬虫的定义 网络爬虫&#xff08;Web Crawler 或 Spider&#xff09;是一种自动化程序&…

算法训练营day24--93.复原IP地址 +78.子集 +90.子集II

一、93.复原IP地址 题目链接&#xff1a;https://leetcode.cn/problems/restore-ip-addresses/ 文章讲解&#xff1a;https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1fA4y1o715 1.1 初…

MyBatis入门案例

实施前的准备工作&#xff1a; 1.准备数据库表2.创建一个新的springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动、lombok&#xff09;3.在application.properties文件中引入数据库连接信息4.创建对应的实体类Emp&#xff08;实体类属性采用驼峰…

终身免费的Navicat数据库,不需要破解,官方支持

终身免费的Navicat数据库&#xff0c;不需要破解&#xff0c;官方支持 卸载了Navicat&#xff0c;很不爽上干货&#xff0c;Navicat免费版下载地址 卸载了Navicat&#xff0c;很不爽 公司不让用那些破解的数据库软件&#xff0c;之前一直使用Navicat。换了几款其他的数据库试了…

WebStorm 2024 for Mac JavaScript前端开发工具

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff08;适合自己的M芯片版或Intel芯片版&#xff09;&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功3、打开访达&#xff0c;点击【文…