CalcGuide · 技术博客主页 / 一页纸学习计划
🔥极高

API 安全与访问治理:从身份到对象级授权

分类:Web 与后端 · 路径:docs/topics/security-governance/README.md

#rest#api#http#openapi

覆盖 OAuth2/JWT、RBAC/ABAC、对象授权、CORS、rate-limit 与 quota

父主题

REST API 设计与实现:从资源建模到可观测 API

子主题(0)

API 安全与访问治理:从身份到对象级授权

0. 元信息

1. 学习路线

威胁模型 → TLS → OAuth2/JWT → scope → 对象授权 → CORS → rate-limit/quota

2. 阶段周数分配

精简子主题不固定周数。按 §3 顺序完成,卡住时回到 RFC、契约样例和可重复请求。

3. 九阶段表

阶段核心知识实践产出学会标准
1术语与边界术语表不混淆相邻概念
2HTTP/标准语义请求矩阵能引用规范解释
3数据与状态schema/状态图正常与冲突可区分
4安全边界威胁清单非法路径被拒绝
5失败语义错误目录客户端能稳定处理
6兼容策略变更表能识别 breaking change
7工具验证curl/collection可重复运行
8自动检查契约测试修改后会报警
9小项目可运行交付第三方可复现

4. 第一周任务

精简版省略固定日程。做一个最小正常请求,再补认证失败、非法输入、冲突、重试与超时。

5. 阶段通用验收

精简版省略;每个产出至少保留命令、预期、实际与版本。

6. 最终验收

精简版省略;以 §3 第 9 阶段和 §9.4 问题口述检查为准。

7. 综合项目

精简版省略;成果并入父主题电商商品 / 订单 API。

本主题贡献

交付物清单

  1. security/oauth_pkce.sh:Authorization Code + PKCE 完整可重跑脚本,含 code_verifier / code_challenge / state / nonce 生成与 redirect_uri 精确匹配、错误用例(state 校验失败、code 已用、verifier 错误);
  2. security/jwt_rs256.{py|go}:RS256 签名与校验 + JWKS endpoint + 短寿命 access_token(≤ 15 min)+ refresh_token rotation(单次使用 + 黑名单)校验;
  3. security/authz.md:≥ 5 条对象授权用例(含 IDOR 攻击复现与修复),证明读 / 写都走 order.owner_id == sub + scope 双层校验;
  4. security/ratelimit.{lua|py} + cors.md:Redis Lua 令牌桶(key = sub + path)+ CORS 白名单 + preflight 演练 + 429 携带 Retry-After 的压测报告。

验收标准

8. 推荐资料

精简版省略;使用 §9.3 和 §9.6 Source。

9. 学习资料汇聚(v0.3 自包含)

9.1 背景与动机

覆盖 OAuth2/JWT、RBAC/ABAC、对象授权、CORS、rate-limit 与 quota。API 一旦被客户端依赖,错误的语义会变成多年兼容成本。我们用规范、可运行样例和失败测试约束选择。

9.2 概念地图

flowchart LR
  Design[设计] --> Contract[HTTP/OpenAPI 契约]
  Contract --> Runtime[实现/网关]
  Runtime --> Client[客户端]
  Runtime --> Evidence[日志/指标/trace]
  Test[契约与失败测试] -.验证.-> Contract
  Test -.验证.-> Runtime

这张图把设计、实现、调用和证据串起来。任何规则都要能落到契约或运行时检查。

9.3 基础知识讲解

9.3.1 论文 / 规范

9.3.2 书

9.3.3 博客 / 文档

9.3.4 人物

9.3.5 方法

9.4 经典问题与经典案例

问题为什么重要最简答案
JWT 是否等于授权影响客户端正确性和长期兼容写清语义、失败码、重试与测试证据
401 与 403 怎么返回影响客户端正确性和长期兼容写清语义、失败码、重试与测试证据
如何防 IDOR影响客户端正确性和长期兼容写清语义、失败码、重试与测试证据
CORS 能否保护服务端影响客户端正确性和长期兼容写清语义、失败码、重试与测试证据
rate-limit key 怎么选影响客户端正确性和长期兼容写清语义、失败码、重试与测试证据
token 如何撤销影响客户端正确性和长期兼容写清语义、失败码、重试与测试证据

9.4.1 实战片段:OAuth2 Authorization Code + PKCE 完整 redirect 流

角色:浏览器(User-Agent)、SPA 客户端(client_id=spa-app)、
     授权服务器(https://auth.example.com)、资源服务器(https://api.example.com)
1) 客户端生成 verifier 与 challenge
   code_verifier  = random_base64url(32..96)        # 例:dBjftJeZ4CVP...B6M
   code_challenge = base64url(sha256(code_verifier))
   code_challenge_method = S256
   state = random_base64url(16)                    # 防 CSRF
   nonce = random_base64url(16)                    # 防 replay
GET https://auth.example.com/authorize
    ?response_type=code
    &client_id=spa-app
    &redirect_uri=https://app.example.com/cb
    &scope=openid%20profile%20orders.read%20orders.write
    &state=g5Kq9...n2
    &nonce=H2x4...8
    &code_challenge=E9Melhoa2OwvFr...Fw
    &code_challenge_method=S256 HTTP/1.1
HTTP/1.1 302 Found
Location: https://app.example.com/cb
    ?code=SplxlOBeZQQYbYS6WxSbIA
    &state=g5Kq9...n2
POST https://auth.example.com/token
Content-Type: application/x-www-form-urlencoded
Accept: application/json

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https://app.example.com/cb
&client_id=spa-app
&code_verifier=dBjftJeZ4CVP...B6M
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 900,
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "scope": "openid profile orders.read orders.write"
}
GET https://api.example.com/orders HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Idempotency-Key: 9f2b6c1a-1f3d-4b8e-9b6c-2a7f0b5c91a2
X-Request-Id: 6a1d2c4b-...
# 1. 本地一次性生成 PKCE pair
verifier=$(openssl rand -base64 64 | tr -d '=+/' | cut -c1-64)
challenge=$(printf %s "$verifier" | openssl dgst -sha256 -binary | base64 | tr '+/' '-_' | tr -d '=')
state=$(openssl rand -hex 16)

# 2. 浏览器跳到授权页(PKCE 公共客户端无需 client_secret)
open "https://auth.example.com/authorize?response_type=code&client_id=spa-app&redirect_uri=https://app.example.com/cb&scope=openid%20profile%20orders.read&state=$state&code_challenge=$challenge&code_challenge_method=S256"

# 3. 回调拿到 code 后换 token
curl -s https://auth.example.com/token \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d redirect_uri=https://app.example.com/cb \
  -d client_id=spa-app \
  -d code_verifier="$verifier"

# 4. 对象授权检查示例(伪代码)
# 读 orders/{id} 前必须满足:order.owner_id == sub 且 orders.read 在 scope 内
# 验证清单(落地对照)
- 公共客户端只走 PKCE,不下发 client_secret
- redirect_uri 精确匹配(不接受通配子域)
- state 与 nonce 在回调里校验
- access_token 短寿命(<=15 min),refresh_token 单次使用 + rotation
- 后端每次请求做对象级授权,不能只靠 scope
- 撤销:refresh token 存哈希 + 黑名单;access token 接受短窗口失效
- 日志不记录 token、code、verifier;只记 sub/jti/trace

9.5 学习难点

9.5 学习难点

9.6 技术标准与接口

9.6.1 Entity

名称版本组织状态 / 可访问性
OpenAPI Specification3.1OpenAPI Initiative正式;Apache-2.0 仓库,规范公开
JSON:API1.1JSON:API 社区正式;公开
JSON Schema2020-12JSON Schema / IETF 社区正式;公开
Problem Details for HTTP APIsRFC 7807IETF已被 RFC 9457 更新;RFC 公开
HALdraft-kelly-json-halIETF Internet-Draft / HAL 社区草案;公开

9.6.2 Scope

OpenAPI 描述 HTTP API;JSON Schema 描述数据约束;JSON:API 与 HAL 约定表示和链接;Problem Details 约定机器可读错误。它们不替代业务授权、事务设计或运行时保护。

9.6.3 Structure

OpenAPI 必会 pathsoperationsparametersrequestBodyresponsescomponentssecuritySchemes;JSON Schema 必会 typerequiredproperties、组合与引用;Problem Details 必会 type/title/status/detail/instance

9.6.4 Ecosystem

实现与工具包括 Swagger UI、Redoc、Spectral、OpenAPI Generator、Postman、Insomnia、Bruno、httpie、curl。API gateway 常用 Apigee、AWS API Gateway、Kong、Envoy。工具默认值不是规范。

9.6.5 Depth Tiers

层级可观察能力
L0知道这些标准解决什么问题
L1看懂 schema、operation 和 problem body
L2能正确编写、校验、生成客户端并调用
L3能解释语义、排错兼容/鉴权/缓存/限流问题
L4能设计扩展、治理规则与跨团队演进机制

本计划目标:L3

9.6.6 Source

10. 常见误区

11. 所有知识点分类(统一规则)

  1. 编程语言 2. 数据结构与算法 3. 计算机基础 4. 工程技术 5. Web 与后端 6. 前端与客户端 7. 数据与人工智能 8. 项目与职业能力 9. 安全与可靠性

本计划归属:Web 与后端 主 + 工程技术 辅。

直接依赖(1)

查看知识图谱 · 热度 🔥极高