安全认证与 API 网关

项目仓库:java-concurrency-security:用于学习使用的的项目。基于 Spring Boot 2.7 的高并发性能调优 + 安全监控完整脚手架,涵盖 JVM 调优、线程池优化、Redis 缓存防护、分库分表、OAuth2.0 认证、API 网关、ELK 日志收集、SkyWalking APM 监控等核心能力。 - AtomGit | GitCode


前言:什么是 API 网关?

类比: API 网关就像一栋办公楼的前台。

  • 访客(客户端)只能进前台,不能直接进办公区
  • 前台要核验访客身份(鉴权)
  • 前台告诉访客去哪个部门(路由)
  • 前台控制访客数量(限流)
  • 某个部门人满了,前台告诉访客改天再来(熔断)
  • 前台还可以限制访客每天能来几次(防爬虫)

没有前台 = 每个部门都要自己处理这些问题,重复又难管理


1. Spring Security OAuth 2.0

1.1 什么是 OAuth 2.0?

类比: OAuth 2.0 就像"代客泊车"。 你去餐厅吃饭,把车钥匙交给泊车员(授权服务器), 泊车员给你一张"取车凭证"(Token),凭这张凭证可以让泊车员把车开出来。 但泊车员不会拿你的钥匙去干别的,他只负责"取车"这一件事。

生活化例子:

复制代码
你(用户)想用微信登录某个 App
1. App 把你跳转到微信(授权服务器)
2. 你输入微信密码,微信确认你的身份
3. 微信跳回 App 并附带"凭证"(Token)
4. App 拿 Token 找微信要你的昵称头像
5. 微信验 Token 有效,返回你的信息

1.2 架构概览

三者的角色:

角色 干什么的 类比
客户端 想要访问资源 顾客
授权服务器 验证身份,颁发 Token 餐厅前台(认证身份)
资源服务器 持有资源,验证 Token 厨房(提供数据)

1.3 授权模式(4 种取 Token 的方式)

类比: 不同场景下,取餐号的方式不同。

模式 适用场景 流程 安全性
authorization_code Web 应用 重定向 + 回调 最高
password 移动端/自家产品 客户端直接拿用户名密码换 Token
client_credentials 服务间调用 只用 clientId/secret
refresh_token Token 续期 用 refresh_token 换新的 -

举例说明:

场景 A:网站登录(authorization_code)

复制代码
1. 浏览器访问 oauth/authorize?client_id=web&redirect=...
2. 跳转登录页,用户输入密码
3. 登录成功跳回网站:https://app.com/callback?code=ABC
4. 网站用 code 换 access_token
5. 拿 access_token 调用 API

场景 B:手机 App(password)

复制代码
1. App 让用户输入用户名密码
2. App 直接调用:POST /oauth/token
   {grant_type=password, username=zhangsan, password=123}
3. 拿到 access_token
4. 调 API

场景 C:内部服务调用(client_credentials)

复制代码
1. 服务 A 想调服务 B
2. A 用自己的 clientId/secret 换 Token(没有用户参与)
3. 拿 Token 调 B

1.4 JWT 令牌(Token 的格式)

类比: JWT 就像一张"盖了章的工作证",信息写在卡上,不需要回总部查。

结构(3 段,用 . 分隔):

复制代码
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMSJ9.signature_here
│     头部(Header)       │      载荷(Payload)     │   签名(Signature)  │
   描述算法               描述数据                  验证没被篡改

Payload 内容(用户信息):

java 复制代码
{
  "sub": "user123",          // 用户 ID
  "name": "张三",
  "role": "USER",
  "exp": 1620000000,         // 过期时间
  "jti": "abc-123"           // Token 唯一编号(用于吊销)
}

1.5 JWT 令牌管理

令牌 有效期 类比 为什么这么短
Access Token 1~2 小时 临时工作证 短 = 一旦泄露,影响小
Refresh Token 7~30 天 长期工作证 用于换新 Access Token

为什么 Access Token 不设一年? 假如设一年有效,被黑客偷走你就完全没办法。 1 小时有效,丢了最多损失 1 小时。

令牌吊销机制(用户主动登出):

复制代码
1. 用户点击"退出登录"
2. 服务端把 Token 的 jti 写入 Redis 黑名单
3. 设置 Redis 过期时间 = Token 剩余有效期
4. 后续所有带这个 Token 的请求都会被网关拦截

1.6 获取 Token 示例

bash 复制代码
# 密码模式(最简单,适合测试)
curl -X POST http://localhost:8080/oauth/token \
  -u "web-app:web-secret-123" \
  -d "grant_type=password&username=user&password=user123"
# 响应:
# {
#   "access_token": "eyJhbGci...",
#   "refresh_token": "eyJhbGci...",
#   "expires_in": 3600
# }

# 用 Token 访问受保护接口
curl -H "Authorization: Bearer eyJhbGci..." \
  http://localhost:8080/api/user/profile

2. Spring Cloud Gateway

2.1 核心功能

再强调一遍: API 网关 = 办公楼前台

2.2 路由配置(访客分流)

类比: 路由就是告诉访客"你要找的部门在几楼"。 路径匹配就像门牌号:/api/user/* 走用户部门,/api/order/* 走订单部门。

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service         # lb:// 表示"按服务名找,做负载均衡"
          predicates:                    # 条件(满足才走这个路由)
            - Path=/api/user/**          # 路径以 /api/user/ 开头
            - Method=GET,POST            # 只能是 GET 或 POST
          filters:                       # 转发前/后做的事
            - StripPrefix=1              # 去掉路径最前面的 1 段(去掉 /api)
            - name: RequestRateLimiter   # 限流(每秒最多 100 个请求)
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200

Predicates 常用匹配(可选"办公位"):

Predicate 作用 类比
Path=/user/** 路径匹配 楼栋+楼层
Method=GET HTTP 方法 进门方式(步行/开车)
Header=X-Token, \d+ Header 匹配 凭证类型
Query=name,zh 参数匹配 携带的物品
After=2024-01-01 时间匹配 营业时间

2.3 全局过滤器(统一安检)

类比: 办公楼大门的统一安检流程,每个访客都要走一遍。

过滤器链执行顺序:

复制代码
1. 请求日志记录("访客张三来访 14:23:45")
2. 限流检查("访客太多,暂不接待")
3. 公开路径放行("来访客走快速通道")
4. Token 校验("请出示工作证")
5. 黑名单检查("对不起,您的证已吊销")
6. 传递用户信息("登记后去 5 楼技术部")
7. 响应日志("访客离开,耗时 15 分钟")

2.4 限流策略(4 种控制"访客量"的方式)

类比: 餐厅限制客人进店的 4 种方法。

算法 特点 类比 适用
固定窗口 简单,1 秒只放 N 个 每 1 分钟发 100 个号,发完等下分钟 低精度要求
滑动窗口 精确,按比例 把窗口分 10 段,每段 10 个号 中等精度
令牌桶 允许突发 水龙头流令牌,桶里积压的能用 API 限流(推荐)
漏桶 平滑 不管来多少,流出速度固定 严格限速

令牌桶通俗理解:

想象一个每秒滴出 10 个令牌的水龙头,访客要进店就拿走 1 个令牌。

  • 平时:每秒进 10 个访客(稳定)
  • 突发:桶里攒了 100 个令牌(长期没人来),可以一次性放进 100 人
  • 桶空了:拒绝进入(限流)

2.5 熔断降级("今日已满,请明天再来")

类比: 餐厅的某个厨师生病了,餐厅立刻贴出告示"今日某菜不可点"。 既不接新单(熔断),又给客户一个备选方案(降级)。

复制代码
filters:
  - name: CircuitBreaker            # 启用熔断
    args:
      name: orderCB                 # 熔断器名字
      fallbackUri: forward:/fallback/order   # 熔断后去哪

熔断器三种状态:

2.6 灰度路由(金丝雀发布)

类比: 新菜品上线,先给 5% 的客人尝尝,没问题再全量铺开。

复制代码
# 20% 的流量走新版本,80% 走老版本
predicates:
  - Path=/api/product/**
  - Weight=gray, 20    # 权重 gray 的 20%

好处:

  • 出问题只影响 20% 的用户
  • 可以观察新版本的实际表现
  • 不需要发布时"停机切换"

3. 实际工作流(端到端)

给你一个完整的请求生命周期,让你理解所有组件怎么配合:

整个流程清晰了: 认证在网关做,授权在业务层做,二者职责分明。

相关推荐
xixixi7777711 小时前
三大 AI 安全里程碑:Akamai 高危风险预警、智能体水印强制落地、PQC 量子安全全产业链统一
大数据·人工智能·安全·ai·大模型·智能体·政策
hz5678914 小时前
电子远程评标系统哪家好?安全、合规、易用平台评测指南
安全·云计算·音视频·实时音视频·信息与通信
MartinYeung514 小时前
[论文学习]大语言模型安全综述:攻击、防御、对齐、度量与护栏的深度解析
学习·安全·语言模型
卓豪终端管理16 小时前
企业数据防泄漏:现代设备控制如何成为终端安全的关键防线
安全
技术不好的崎鸣同学18 小时前
[GXYCTF2019]Ping Ping Ping 思路及解法
网络·安全·web安全
GEO_youxuan21 小时前
2026年儿童电话手表推荐:定位精度、通话安全与健康监测深度横评
安全
数据知道1 天前
安全报告怎么写才专业:渗透测试报告模板与踩坑
安全·网络安全·漏洞修复·安全报告·渗透测试报告
doiito1 天前
【安全,架构】RustyVault 项目深度分析报告以及和HashiCorp Vault的差异
后端·安全·rust
2601_962851741 天前
计算机毕业设计之基于SSM的网络安全课程资源分享平台
vue.js·算法·安全·web安全·yolo·目标检测·课程设计