拦截器魔法:Spring MVC中的防重放守护者

embedded/2024/12/25 1:58:55/

目录

  1. 简介
  2. HandlerInterceptorAdapter vs HandlerInterceptor
  3. 创建一个防重放拦截器
  4. 注册拦截器
  5. 路径模式匹配
  6. 适配器模式的魅力
  7. 总结

简介

在构建安全可靠的Web应用程序时,防止请求重放攻击是一项关键任务。当用户或系统发出的请求被恶意第三方捕获并重复发送给服务器时,就会发生重放攻击。这可能导致不必要的操作被执行,如重复下单、重复支付等。为了保护我们的应用免受此类威胁,我们可以利用Spring MVC框架提供的强大工具——HandlerInterceptor来实现防重放机制。

HandlerInterceptorAdapter vs HandlerInterceptor

当你决定为自己的应用添加自定义拦截逻辑时,可能会面临选择:是继承 HandlerInterceptorAdapter 还是直接实现 HandlerInterceptor 接口?两者之间的差异在于设计哲学和代码的简洁性。

  • HandlerInterceptorAdapter 是一个适配器类,它实现了 HandlerInterceptor 接口,并提供了所有方法的空实现。因此,如果你只需要覆盖部分方法,使用这个适配器可以让你的代码更加简洁。
  • HandlerInterceptor 接口则要求你必须显式地实现接口中定义的所有方法。这种方式虽然可能引入一些冗余代码,但它提供了更高的透明度,因为你清楚地知道有哪些方法需要处理。
  • 总结:extends HandlerInterceptorAdapter 只重写需要的方法即可,implements HandlerInterceptor需要重写所有方法,可能增加代码冗余

创建一个防重放拦截器

为了确保相同的请求不会被多次处理,我们需要在每次接收到POST请求时检查其唯一标识符(例如订单号或时间戳),并与服务器端存储的历史记录进行比较。下面是一个简单的防重放拦截器实现示例,这里我们使用Redis作为存储介质:

java">@Component
public class AntiReplayInterceptor extends HandlerInterceptorAdapter {private static final String REQUEST_ID = "requestId";private static final long EXPIRE_TIME_IN_SECONDS = 60 * 5;@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if ("POST".equals(request.getMethod()) && request.getRequestURI().startsWith("/inner/public/syncOrder/v1")) {// 获取请求体中的唯一标识符SynYxcRequest orderSyncDto = extractRequestBody(request);String requestId = orderSyncDto.getRequestId();// 检查是否已经处理过该请求IDif (redisTemplate.opsForValue().get(requestId) != null) {response.setStatus(HttpServletResponse.SC_CONFLICT);return false;} else {// 将请求ID存入Redis,并设置过期时间redisTemplate.opsForValue().set(requestId, "processed", EXPIRE_TIME_IN_SECONDS, TimeUnit.SECONDS);}}return true;}private SynYxcRequest extractRequestBody(HttpServletRequest request) throws IOException {ObjectMapper objectMapper = new ObjectMapper();return objectMapper.readValue(request.getReader().lines().collect(Collectors.joining(System.lineSeparator())), SynYxcRequest.class);}
}

注册拦截器

有了拦截器之后,我们需要将其注册到Spring MVC配置中,以确保它能够应用于指定的请求路径:

java">@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate AntiReplayInterceptor antiReplayInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(antiReplayInterceptor).addPathPatterns("/inner/public/syncOrder/v1");}
}

路径模式匹配

如果不指定 .addPathPatterns() 方法,那么拦截器将会默认应用到所有路径。为了避免不必要的性能开销以及潜在的问题,你应该总是明确地定义你要拦截的路径模式。此外,你还可以使用 .excludePathPatterns() 来排除不需要拦截的路径。

适配器模式的魅力

通过使用 HandlerInterceptorAdapter,你可以轻松地只覆盖那些对你重要的方法,而无需关心其他方法。这种设计不仅简化了代码,也提高了可维护性。当然,如果你更喜欢一切都在掌控之中,直接实现 HandlerInterceptor 接口也是一个不错的选择。

总结

通过本文介绍的内容,我们了解了如何利用Spring MVC中的 HandlerInterceptorHandlerInterceptorAdapter 来构建一个高效的防重放拦截器。无论你是追求代码简洁还是完全控制,Spring都提供了灵活的解决方案,帮助你在Web开发的世界里游刃有余。希望这些知识能为你的项目增添一份安全保障,让每一次请求都能得到恰当的处理。


http://www.ppmy.cn/embedded/148497.html

相关文章

MySQL InnoDB 存储引擎详解

InnoDB 是 MySQL 中最常用、最强大的存储引擎之一&#xff0c;其支持事务、外键、行级锁等特性&#xff0c;非常适合对可靠性、并发性要求较高的场景。本文将详细解析 InnoDB 的核心特性、内部机制以及使用场景&#xff0c;帮助你更好地理解和优化 MySQL 数据库。 1. 为什么选择…

【漏洞复现】CVE-2022-45206 CVE-2023-38905 SQL Injection

漏洞信息 NVD - CVE-2022-45206 Jeecg-boot v3.4.3 was discovered to contain a SQL injection vulnerability via the component /sys/duplicate/check. NVD - CVE-2023-38905 SQL injection vulnerability in Jeecg-boot v.3.5.0 and before allows a local attacker to…

Scala项目(图书管理系统)

3、service BookService package org.app package serviceimport org.app.dao.{BookDAO, BorrowRecordDAO} import org.app.models.{BookModel, BorrowRecordModel}import java.time.LocalDateTime import scala.collection.mutable.ListBuffer// 图书业务逻辑层 class BookS…

Airwallex空中云汇实现独立站安全高效收款

在数字化浪潮的强劲推动下&#xff0c;全球贸易正加快迈向数字化转型&#xff0c;其中跨境电商已深度融入国际贸易体系&#xff0c;成为促进全球经济互联互通的重要力量。 而独立站在这一领域中扮演着 举足轻重的角色&#xff0c;吸引了越来越多的商家投身于其建设之中&#xf…

[python]使用flask-caching缓存数据

简介 Flask-Caching 是 Flask 的一个扩展&#xff0c;为任何 Flask 应用程序添加了对各种后端的缓存支持。它基于 cachelib 运行&#xff0c;并通过统一的 API 支持 werkzeug 的所有原始缓存后端。开发者还可以通过继承 flask_caching.backends.base.BaseCache 类来开发自己的…

深入解析 StarRocks 物化视图:全方位的查询改写机制

小编导读&#xff1a; 本文将重点介绍如何利用物化视图进行查询改写。文章将全面介绍物化视图的基本原理、关键特性、应用案例、使用场景、代码细节以及主流大数据产品的物化视图改写能力对比。 物化视图在 StarRocks 中扮演着至关重要的角色&#xff0c;它是进行数据建模和加速…

OpenFeign服务接口调用理解

目录 什么是openfeign&#xff1a; feign的处理流程&#xff1a; openfeign超时控制&#xff1a; Feign 超时控制概述 配置&#xff1a; 全局配置&#xff1a; 指定配置&#xff1a; openfeign重试机制&#xff1a; 1. Feign 的重试机制 2. 方法一&#xff1a;启用 Fei…

Chromium CDP 开发(十):Chromium 中增加自己的Domain

1. 引言 在深入了解了 Chromium CDP&#xff08;Chrome DevTools Protocol&#xff09;的开发过程之后&#xff0c;接下来我们将探讨如何创建一个自定义的 CDP Domain。通过为特定功能创建自己的 CDP Domain&#xff0c;可以避免对已有的 CDP 进行侵入式修改&#xff0c;从而更…