跳到主要内容

防护组件 (yudao-spring-boot-starter-protection)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 组件详解
  6. 依赖关系分析
  7. 性能与可扩展性
  8. 故障排查指南
  9. 结论
  10. 附录:配置与使用示例

简介

本文件面向 yudao-spring-boot-starter-protection 防护组件,系统化阐述以下能力与实现细节:

  • 幂等性保护(IdempotentAspect):请求去重、重复提交防护、基于 Token 的并发控制
  • 限流器(RateLimiterAspect):滑动窗口计数器算法、限流策略与 Redis 实现
  • API 签名(ApiSignatureAspect):签名算法、时间戳验证、防重放攻击
  • 分布式锁与接口防刷、恶意请求识别等安全防护特性
  • 提供配置与使用示例,帮助在不同业务场景中选择合适的防护策略

项目结构

该组件以 Spring AOP 切面为核心,围绕注解驱动的拦截器组织功能模块,并通过 Redis 进行状态持久化与分布式协调。

Mermaid Diagram Code:

graph TB
subgraph "防护组件"
A["IdempotentAspect<br/>幂等性切面"]
B["RateLimiterAspect<br/>限流切面"]
C["ApiSignatureAspect<br/>签名切面"]
end
subgraph "基础设施"
R["Redis<br/>分布式存储"]
L["RedisDistributionLockUtils<br/>分布式锁工具"]
end
A --> R
B --> R
C --> R
A -. 可选依赖 .-> L

图表来源

章节来源

核心组件

  • 幂等性保护(IdempotentAspect):通过 Redis SET IF NOT EXIST 实现“令牌”锁定,避免同一请求在超时窗口内重复执行;支持异常时自动清理键,降低脏锁风险。
  • 限流器(RateLimiterAspect):基于 Redis 的滑动窗口计数器,按固定时间窗口统计请求数量,超过阈值则拒绝。
  • API 签名(ApiSignatureAspect):对请求参数、请求体、请求头进行规范化排序拼接后做 SHA-256 签名;结合时间戳容差与一次性随机数(nonce)防重放。

章节来源

架构总览

三类切面均采用注解驱动拦截目标方法,解析 Key 后委托各自的 DAO/工具完成原子性判断或状态维护,最终在命中策略时抛出统一错误码。

Mermaid Diagram Code:

sequenceDiagram
participant Client as "客户端"
participant MVC as "Spring MVC"
participant AOP as "防护切面"
participant DAO as "Redis/DAO"
participant Biz as "业务方法"
Client->>MVC : "HTTP 请求"
MVC->>AOP : "进入被注解方法"
AOP->>DAO : "解析 Key 并执行判定/原子操作"
DAO-->>AOP : "返回结果"
alt "命中防护策略"
AOP-->>Client : "抛出统一错误码"
else "通过"
AOP->>Biz : "继续执行业务"
Biz-->>AOP : "返回结果"
AOP-->>Client : "正常响应"
end

图表来源

组件详解

幂等性保护(IdempotentAspect)

  • 核心思想:以“请求 Key”为维度,在指定超时时间内对同一请求进行“令牌”锁定,避免重复执行。
  • 关键流程:
    1. 解析 Key(支持多种 KeyResolver)
    2. 使用 Redis SET IF NOT EXIST 原子设置键值(带过期时间)
    3. 若失败,视为重复请求,抛出统一错误码
    4. 正常执行业务;若发生异常且配置允许,删除 Key 防止脏锁
  • 适用场景:下单、转账、扣款等高危操作;按钮重复点击;前端重试导致的重复提交
  • 与分布式锁的关系:可配合 RedisDistributionLockUtils 实现更细粒度的资源互斥

Mermaid Diagram Code:

flowchart TD
Start(["进入切面"]) --> ResolveKey["解析请求 Key"]
ResolveKey --> TryLock["Redis SET IF NOT EXIST 上锁"]
TryLock --> Acquired{"上锁成功?"}
Acquired --> |否| Reject["抛出重复请求错误"]
Acquired --> |是| Exec["执行业务方法"]
Exec --> Exception{"是否发生异常?"}
Exception --> |是| MaybeDelete["根据配置决定是否删除 Key"]
Exception --> |否| Done["返回结果"]
MaybeDelete --> Done

图表来源

章节来源

限流器(RateLimiterAspect)

  • 核心思想:基于滑动窗口计数器,统计固定时间窗口内的请求数,超过阈值则限流。
  • 关键流程:
    1. 解析 Key(支持多种 KeyResolver)
    2. 调用 Redis DAO 执行“尝试获取配额”原子操作
    3. 失败则抛出统一错误码,提示请求过于频繁
  • 适用场景:秒杀、大促活动、接口滥用防护、爬虫治理
  • 策略建议:按接口维度、IP 维度、账号维度组合 Key;合理设置窗口大小与阈值

Mermaid Diagram Code:

flowchart TD
S(["进入切面"]) --> K["解析限流 Key"]
K --> Acquire["Redis 原子尝试获取配额"]
Acquire --> Allowed{"是否允许?"}
Allowed --> |否| TooMany["抛出限流错误"]
Allowed --> |是| Proceed["继续执行业务"]

图表来源

章节来源

API 签名(ApiSignatureAspect)

  • 核心思想:对请求参数、请求体、请求头进行规范化排序拼接后做 SHA-256 签名;结合时间戳容差与一次性随机数(nonce)抵御重放攻击。
  • 关键流程:
    1. 校验请求头关键字段(appId、timestamp、nonce、sign),并检查时间戳偏差
    2. 校验 nonce 是否已在缓存中使用(一次性)
    3. 按约定规则构建签名字符串并计算哈希
    4. 通过后将 nonce 写入缓存并设置 TTL(通常为时间戳容差的两倍)
  • 适用场景:开放平台、第三方集成、移动端 SDK、服务间鉴权

Mermaid Diagram Code:

sequenceDiagram
participant C as "客户端"
participant S as "ApiSignatureAspect"
participant R as "Redis"
C->>S : "携带 appId/timestamp/nonce/sign 的请求"
S->>S : "校验头部字段与时间戳容差"
S->>R : "查询 nonce 是否已使用"
alt "nonce 已使用或不合法"
S-->>C : "拒绝请求"
else "nonce 未使用"
S->>S : "构建签名字符串并计算哈希"
alt "签名一致"
S->>R : "写入 nonceTTL=容差*2"
S-->>C : "放行"
else "签名不一致"
S-->>C : "拒绝请求"
end
end

图表来源

章节来源

分布式锁、接口防刷、恶意请求识别

  • 分布式锁:组件提供 Redis 分布式锁工具,支持尝试加锁与解锁,可用于更细粒度的资源互斥与竞态控制。
  • 接口防刷:结合限流与签名,可对高频重复请求、重放攻击、伪造请求进行有效拦截。
  • 恶意请求识别:通过 nonce 一次性机制、时间戳容差、签名一致性等多维校验,降低恶意请求成功率。

章节来源

依赖关系分析

  • 组件耦合
    • 幂等与限流均依赖 Redis 原子操作能力,通过 DAO 层抽象屏蔽具体实现
    • 签名依赖 Redis 缓存 nonce,确保一次性使用
  • 外部依赖
    • Spring AOP、AspectJ、RedisTemplate
    • 统一错误码与通用异常体系
  • 潜在风险
    • Key 解析策略不当可能导致误伤或绕过
    • Redis 可用性直接影响防护效果

Mermaid Diagram Code:

graph LR
Idem["IdempotentAspect"] --> Redis["Redis 原子操作"]
Rate["RateLimiterAspect"] --> Redis
Sign["ApiSignatureAspect"] --> Redis
Idem -. 可选 .-> Lock["RedisDistributionLockUtils"]

图表来源

章节来源

性能与可扩展性

  • Redis 原子操作具备高吞吐与低延迟特性,适合高并发场景
  • Key 设计应尽量短小且唯一,避免热点 Key
  • TTL 设置需平衡防护强度与内存占用
  • 可扩展点:自定义 KeyResolver、替换 Redis DAO、引入本地缓存兜底

故障排查指南

  • 幂等性误判
    • 现象:正常请求被判定为重复
    • 排查:确认 Key 解析是否稳定;检查超时时间是否过短;核对异常清理策略
  • 限流误伤
    • 现象:正常流量被限流
    • 排查:调整窗口大小与阈值;区分接口/用户/IP 维度;评估并发峰值
  • 签名失败
    • 现象:签名一致但被拒绝
    • 排查:nonce 是否已使用;时间戳是否超出容差;签名字符串构建规则是否一致
  • Redis 不可用
    • 现象:所有防护失效
    • 排查:检查连接配置、网络、哨兵/集群状态;必要时降级放行或熔断

章节来源

结论

yudao-spring-boot-starter-protection 通过注解驱动的 AOP 切面,将幂等、限流、签名三大安全能力以统一方式接入业务,配合 Redis 原子操作实现高可靠防护。合理设计 Key 与策略参数,可在保证用户体验的同时有效抵御重复提交、滥用与重放攻击。

附录:配置与使用示例

  • 幂等性保护
    • 在目标方法上添加幂等注解,配置 Key 解析器、超时时间与异常时是否删除 Key
    • 场景:支付回调、订单创建、转账扣款
  • 限流
    • 在目标方法上添加限流注解,配置窗口大小、阈值与 Key 解析器
    • 场景:秒杀、大促、接口滥用防护
  • API 签名
    • 在目标方法上添加签名注解,配置 appId/nonce/timestamp/sign 请求头名称与时间戳容差
    • 场景:开放平台、第三方集成、移动端 SDK

章节来源

用户文档
AI 助手
Agent 列表
请选择一个 Agent 开始对话
AI 问答