Files
aiot-platform-cloud/.qoder/repowiki/zh/content/安全设计/API安全防护.md

365 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API安全防护
<cite>
**本文引用的文件**
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java)
- [ApiSignature.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/annotation/ApiSignature.java)
- [ViewshApiSignatureAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/config/ViewshApiSignatureAutoConfiguration.java)
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java)
- [RateLimiter.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/annotation/RateLimiter.java)
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java)
- [Idempotent.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/annotation/Idempotent.java)
- [ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java)
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java)
- [ApiSignatureTest.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/test/java/com/viewsh/framework/signature/core/ApiSignatureTest.java)
</cite>
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 引言
本文件面向AIOT平台云项目的API安全防护系统化梳理请求验证机制、频率限制、防重放攻击、API日志记录与审计、以及注入攻击防护策略并提供可落地的配置与规则示例帮助开发者在不牺牲易用性的前提下构建高可靠、可运维的API安全体系。
## 项目结构
本项目围绕“保护”与“安全”两大框架模块提供API安全能力
- 视图框架保护模块viewsh-spring-boot-starter-protection提供签名验证、限流、幂等控制等横切能力。
- 视图框架安全模块viewsh-spring-boot-starter-security提供认证授权、全局异常处理、操作日志审计等安全基础能力。
```mermaid
graph TB
subgraph "保护框架"
SIG["签名验证<br/>ApiSignatureAspect"]
RL["频率限制<br/>RateLimiterAspect"]
IDE["幂等控制<br/>IdempotentAspect"]
end
subgraph "安全框架"
SEC["安全自动配置<br/>ViewshSecurityAutoConfiguration"]
LOG["操作日志<br/>LogRecordServiceImpl"]
end
CLI["客户端"] --> SIG
CLI --> RL
CLI --> IDE
SIG --> SEC
RL --> SEC
IDE --> SEC
SEC --> LOG
```
图表来源
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L1-L174)
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L1-L61)
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L1-L69)
- [ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java#L1-L95)
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L1-L92)
章节来源
- [ViewshApiSignatureAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/config/ViewshApiSignatureAutoConfiguration.java#L1-L28)
- [ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java#L1-L95)
## 核心组件
- 请求签名验证基于注解拦截器对请求头参数进行非空与时效校验生成并比对签名同时利用Redis记录nonce以抵御重放。
- 频率限制支持多种Key解析器默认/用户/IP/节点/SpEL基于Redis实现滑动窗口风格的限流。
- 幂等控制通过Redis SET IF ABSENT实现分布式锁避免同一请求重复执行。
- 安全与日志:统一的认证入口、异常处理与操作日志记录,便于审计与追踪。
章节来源
- [ApiSignature.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/annotation/ApiSignature.java#L1-L60)
- [RateLimiter.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/annotation/RateLimiter.java#L1-L63)
- [Idempotent.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/annotation/Idempotent.java#L1-L64)
- [ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java#L1-L95)
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L1-L92)
## 架构总览
下图展示API请求在进入业务控制器前的关键安全拦截链路与职责分工
```mermaid
sequenceDiagram
participant C as "客户端"
participant G as "网关/应用"
participant S as "签名拦截器<br/>ApiSignatureAspect"
participant R as "限流拦截器<br/>RateLimiterAspect"
participant I as "幂等拦截器<br/>IdempotentAspect"
participant B as "业务控制器"
participant L as "操作日志<br/>LogRecordServiceImpl"
C->>G : "HTTP 请求"
G->>S : "进入签名验证"
S-->>G : "通过/拒绝"
G->>R : "进入频率限制"
R-->>G : "通过/拒绝"
G->>I : "进入幂等控制"
I-->>G : "通过/拒绝"
G->>B : "执行业务逻辑"
B-->>G : "返回结果"
G->>L : "异步记录操作日志"
L-->>G : "完成"
G-->>C : "HTTP 响应"
```
图表来源
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L40-L52)
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L40-L57)
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L39-L66)
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L32-L49)
## 详细组件分析
### 请求签名验证(防重放与请求完整性)
- 核心流程
- 请求头参数校验appId、timestamp、nonce、sign均不能为空nonce长度不少于10位timestamp与当前时间偏差不超过timeout。
- 签名生成与比对:按固定顺序拼接请求参数、请求体、请求头与密钥,计算摘要并与客户端传入签名比对。
- 防重放将nonce写入Redis并设置TTLTTL建议为允许时间差的两倍确保nonce只被使用一次。
- 关键点
- appId对应appSecret由Redis DAO加载缺失时直接拒绝。
- 失败时返回明确错误码,避免泄露内部细节。
- 配置要点
- timeout与timeUnit用于控制允许的时间漂移窗口。
- 可自定义请求头字段名appId、timestamp、nonce、sign以适配不同客户端。
- 常见问题
- nonce未设置或过短导致校验失败。
- timestamp格式非法或超窗导致拒绝。
- 签名算法不一致导致比对失败。
```mermaid
flowchart TD
Start(["进入签名验证"]) --> H1["校验请求头参数<br/>appId/timestamp/nonce/sign"]
H1 --> H2{"参数合法?"}
H2 -- 否 --> Fail["拒绝请求"]
H2 -- 是 --> S1["加载appSecret"]
S1 --> S2["生成服务端签名字符串"]
S2 --> S3["计算摘要并与客户端签名比对"]
S3 --> S4{"签名一致?"}
S4 -- 否 --> Fail
S4 -- 是 --> N1["写入nonce到Redis<br/>TTL=timeout*2"]
N1 --> N2{"写入成功?"}
N2 -- 否 --> Repeated["重复请求,拒绝"]
N2 -- 是 --> Pass["通过"]
```
图表来源
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L54-L80)
- [ApiSignature.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/annotation/ApiSignature.java#L20-L28)
章节来源
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L54-L123)
- [ApiSignature.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/annotation/ApiSignature.java#L18-L58)
- [ViewshApiSignatureAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/config/ViewshApiSignatureAutoConfiguration.java#L15-L26)
- [ApiSignatureTest.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/test/java/com/viewsh/framework/signature/core/ApiSignatureTest.java#L37-L78)
### 频率限制(滑动窗口与分布式限流)
- 核心流程
- 通过Key解析器生成限流Key默认/用户/IP/节点/SpEL表达式
- 使用Redis尝试获取令牌滑动窗口风格若失败则触发限流异常。
- Key解析器
- 默认:全局限流。
- 用户:按用户维度限流。
- 客户端IP按来源IP限流。
- 服务器节点:按节点维度限流。
- SpEL表达式按动态表达式生成Key。
- 配置要点
- time与timeUnit定义统计周期。
- count定义周期内允许的最大请求数。
- keyResolver与keyArg决定限流粒度与表达式。
```mermaid
classDiagram
class RateLimiter {
+int time
+TimeUnit timeUnit
+int count
+String message
+Class~RateLimiterKeyResolver~ keyResolver
+String keyArg
}
class RateLimiterAspect {
+beforePointCut(joinPoint, rateLimiter)
}
RateLimiterAspect --> RateLimiter : "读取注解配置"
```
图表来源
- [RateLimiter.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/annotation/RateLimiter.java#L24-L62)
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L40-L57)
章节来源
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L26-L57)
- [RateLimiter.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/annotation/RateLimiter.java#L24-L62)
### 幂等控制(防重复提交)
- 核心流程
- 通过Key解析器生成幂等Key默认/用户/SpEL表达式
- 使用Redis SET IF ABSENT加分布式锁若失败则判定为重复请求。
- 正常执行后释放锁异常时可按配置删除Key避免阻塞后续请求。
- 配置要点
- timeout与timeUnit控制锁持有时间。
- deleteKeyWhenException控制异常时是否删除Key。
- keyResolver与keyArg决定幂等粒度。
```mermaid
flowchart TD
A["进入幂等拦截"] --> K["解析Key"]
K --> L["SET IF ABSENT加锁"]
L --> L1{"加锁成功?"}
L1 -- 否 --> E["重复请求,拒绝"]
L1 -- 是 --> X["执行业务逻辑"]
X --> X1{"执行成功?"}
X1 -- 是 --> U["释放锁"]
X1 -- 否 --> D{"异常删除Key?"}
D -- 是 --> R["删除Key"]
D -- 否 --> T["保留Key"]
U --> Z["返回结果"]
R --> Z
T --> Z
```
图表来源
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L39-L66)
- [Idempotent.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/annotation/Idempotent.java#L21-L63)
章节来源
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L25-L66)
- [Idempotent.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/annotation/Idempotent.java#L21-L63)
### API日志记录与审计
- 日志内容
- 请求链路追踪ID、用户信息登录态、请求方法、URL、客户端IP、UA等。
- 操作类型、子类型、业务编号、动作描述与扩展字段。
- 异步记录
- 通过异步方式落库,避免阻塞主请求路径。
- 异常时记录错误日志,便于定位问题。
- 审计价值
- 支持事后审计、合规追溯与问题复盘。
```mermaid
sequenceDiagram
participant B as "业务层"
participant L as "日志服务<br/>LogRecordServiceImpl"
participant API as "操作日志API"
B->>L : "记录操作日志"
L->>L : "填充追踪ID/用户/请求信息"
L->>API : "异步创建操作日志"
API-->>L : "完成"
L-->>B : "返回"
```
图表来源
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L32-L49)
章节来源
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L26-L92)
### 安全配置与自动装配
- 安全自动配置
- 提供认证入口、权限不足处理、密码加密器、Token认证过滤器、安全上下文策略等。
- 签名自动配置
- 注册签名拦截器与Redis DAO依赖Redis自动装配。
章节来源
- [ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java#L32-L94)
- [ViewshApiSignatureAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/config/ViewshApiSignatureAutoConfiguration.java#L15-L26)
## 依赖分析
- 组件耦合
- 签名/限流/幂等均通过AOP拦截器接入与业务方法解耦。
- Redis DAO负责底层存储Key解析器提供灵活的限流/幂等粒度。
- 外部依赖
- Redis签名nonce、限流令牌、幂等锁均依赖Redis。
- Spring Security提供认证授权基础设施。
- 潜在风险
- Redis不可用将影响所有保护能力。
- Key解析不当可能导致限流/幂等粒度过粗或过细。
```mermaid
graph LR
ASPECT_SIG["签名拦截器"] --> DAO_SIG["签名Redis DAO"]
ASPECT_RL["限流拦截器"] --> DAO_RL["限流Redis DAO"]
ASPECT_IDE["幂等拦截器"] --> DAO_IDE["幂等Redis DAO"]
SEC_AUTO["安全自动配置"] --> FILTER["Token认证过滤器"]
SIG_AUTO["签名自动配置"] --> ASPECT_SIG
```
图表来源
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L38-L40)
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L35-L37)
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L34-L37)
- [ViewshApiSignatureAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/config/ViewshApiSignatureAutoConfiguration.java#L18-L26)
- [ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java#L70-L74)
## 性能考虑
- Redis热点
- 高频限流/幂等/签名nonce可能形成热点建议
- 合理设置Key TTL与统计周期避免长期占用。
- 使用更细粒度的Key如用户/IP/节点降低单Key压力。
- 异步日志
- 操作日志采用异步写入,减少对主请求的影响。
- AOP开销
- 注解拦截器在请求链路中增加少量开销,建议在高频接口上按需启用。
## 故障排查指南
- 签名失败
- 检查请求头字段是否齐全、nonce长度是否满足要求、timestamp是否在允许范围内。
- 确认服务端与客户端使用的签名算法一致。
- 核对appId对应的appSecret是否正确配置。
- 重复请求/重放
- 检查nonce是否已存在于Redis且未过期。
- 确认nonce的TTL是否覆盖允许的时间漂移范围。
- 请求过快
- 调整count与time参数或切换更细粒度的Key解析器。
- 检查是否存在突发流量导致的瞬时峰值。
- 幂等冲突
- 检查timeout是否过短导致业务未完成即释放锁。
- 若异常删除Key策略开启确认业务异常时Key已被清理。
- 日志未记录
- 检查异步线程池与网络调用是否正常。
- 关注异常日志输出,定位具体失败原因。
章节来源
- [ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L48-L52)
- [RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L52-L56)
- [IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L51-L53)
- [LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L45-L48)
## 结论
通过签名验证、限流、幂等控制与操作日志的协同本项目在不侵入业务的前提下提供了完善的API安全防护能力。结合合理的配置与监控告警可在保证用户体验的同时显著提升系统的抗攻击能力与可审计性。
## 附录
### 配置与规则示例
- 签名验证
- 在接口上添加签名注解设置timeout与timeUnit以匹配业务时延自定义请求头字段名以适配客户端。
- 示例路径参考:[ApiSignature.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/annotation/ApiSignature.java#L18-L58)
- 频率限制
- 选择合适的Key解析器默认/用户/IP/节点/SpEL调整count与time参数。
- 示例路径参考:[RateLimiter.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/annotation/RateLimiter.java#L24-L62)
- 幂等控制
- 根据业务需求选择Key解析器设置timeout与deleteKeyWhenException。
- 示例路径参考:[Idempotent.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/annotation/Idempotent.java#L21-L63)
- 安全与日志
- 启用安全自动配置与操作日志记录,确保认证、异常处理与审计完备。
- 示例路径参考:[ViewshSecurityAutoConfiguration.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/security/config/ViewshSecurityAutoConfiguration.java#L32-L94)[LogRecordServiceImpl.java](file://viewsh-framework/viewsh-spring-boot-starter-security/src/main/java/com/viewsh/framework/operatelog/core/service/LogRecordServiceImpl.java#L26-L92)
### 常见攻击场景与应对
- 参数篡改与重放
- 通过签名验证与nonce防重放机制抵御。
- 参考:[ApiSignatureAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/signature/core/aop/ApiSignatureAspect.java#L54-L80)
- 高频刷量
- 使用限流拦截器,按用户/IP/节点等维度精细化限流。
- 参考:[RateLimiterAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/ratelimiter/core/aop/RateLimiterAspect.java#L40-L57)
- 重复提交
- 使用幂等拦截器,避免同一请求多次执行造成副作用。
- 参考:[IdempotentAspect.java](file://viewsh-framework/viewsh-spring-boot-starter-protection/src/main/java/com/viewsh/framework/idempotent/core/aop/IdempotentAspect.java#L39-L66)
- SQL注入/XSS/命令注入
- 本仓库未提供专门的注入防护组件。建议在输入参数校验、数据库访问层与前端渲染层分别实施:
- 输入参数校验:使用参数校验框架与白名单策略。
- SQL访问使用ORM映射与参数化查询避免动态拼接。
- XSS对输出进行HTML转义与CSP策略。
- 命令注入:禁止动态执行外部命令,使用沙箱或受控接口。
- 参考:通用安全实践与参数校验组件(本仓库未提供专用注入防护模块)。