三十天精通 认证授权
—— 给 Go 开放平台工程师的路线
从 HTTP Basic 到 OAuth 2.1,从 JWT 到 mTLS,从 RBAC 到 Google Zanzibar。 六个阶段覆盖:基础认证 · 令牌与 JWT · OAuth 2.0 全家桶 · OIDC 与企业身份 · 授权模型 · 开放平台实战。 节奏:每天 45–90 分钟,先读规范 / 论文,后用 Go 实现最小可运行的样例。 原则——对着 RFC 读 → 画时序图 → 写 Go 实现 → 复盘攻击面。
阶段总览
基础认证
把所有"老话题"一次性补齐。 HTTP Basic / Cookie / Session 是后面所有协议的语义基础; 密码学和 TLS 是所有 token 安全性的物理基础。 跳过这一阶段直接学 OAuth,会看着规范不知道为什么要这么设计。
net/http 写一个支持 Cookie Session 登录 + bcrypt 存密码 + TOTP 二次验证的最小 demo令牌与 JWT
JWT 是 OAuth / OIDC 时代的事实载荷格式,但也是事故重灾区。 这一阶段先把 JWS / JWE / JWK / JWA 一族规范理清, 再专门用一天复盘 JWT 的著名漏洞, 最后用 Go 实现带 JWKS 轮换的双 token 登录系统。
alg=none 漏洞 · alg 混淆 · Key Confusion · 拒绝列表设计 · JWKS 端点OAuth 2.0 全家桶 ★ 开放平台核心
整整一周专门给 OAuth 2.0。 开放平台的"接入第三方应用",本质就是在搭 OAuth Authorization Server。 不只要懂"用哪个流程",更要懂"为什么是这个流程"—— Implicit Flow 为什么被废、PKCE 解决什么问题、DPoP 又对 Bearer 做了什么补充。
OIDC 与企业身份
OAuth 解决"授权",OIDC 在它之上解决"认证"—— 开放平台里几乎所有"用 X 账号登录"都是这两套协议的组合。 企业客户接入则还要面对 SAML 这套上一个时代的协议,以及 SCIM 这种"用户/组同步"标准。
.well-known/openid-configuration · JWKS 端点 · Dynamic Client Registration RFC 7591授权模型 (AuthZ)
认证解决"你是谁",授权解决"你能干什么"。 RBAC 适合管理后台,ABAC 适合复杂规则,ReBAC 适合"文档 / 资源"型权限(典型代表是 Google Docs)。 开放平台一般是组合:scope + RBAC 给 API 接入,资源级权限走 ReBAC。
开放平台实战 ★ 业务落地
最后五天,把所有协议落到真实的开放平台场景: 签名验证(API Key + HMAC)、三方应用接入与配额、服务间 mTLS、零信任架构, 最终用 Ory Hydra + Casbin + Go 搭一个能跑的小型 IAM。
规范 / RFC 速查
这一行是这套路线最重要的资料。 认证授权领域所有"博客知识"最终都要回到这几篇规范才有定论。 建议每天学习的最后 15 分钟,对着 RFC 看一遍今天的主题。
| 编号 | 规范 | 说明 | 对应阶段 |
|---|---|---|---|
| RFC 7617 | HTTP Basic Auth | 最简单的 HTTP 认证方案,base64(user:pass) | P1 · Day 1 |
| RFC 6238 | TOTP 时间型一次性密码 | Google Authenticator / Authy 的核心算法 | P1 · Day 5 |
| WebAuthn L3 | W3C WebAuthn / Passkey | 无密码认证的事实标准,基于公私钥 | P1 · Day 5 |
| RFC 7519 | JSON Web Token (JWT) | Token 的载荷格式定义 | P2 · Day 6 |
| RFC 7515 | JSON Web Signature (JWS) | JWT 默认形态——只签名不加密 | P2 · Day 6 |
| RFC 7516 | JSON Web Encryption (JWE) | 需要保密的 JWT 用这个 | P2 · Day 6 |
| RFC 7517 | JSON Web Key (JWK / JWKS) | 公钥分发的标准格式 | P4 · Day 18 |
| RFC 6749 | OAuth 2.0 核心 | 开放平台的"宪法"——必须通读 | P3 · Day 10 |
| RFC 6750 | Bearer Token 使用 | Authorization: Bearer xxx 的来源 | P3 · Day 14 |
| RFC 7636 | PKCE | 移动 / SPA 场景的必备加固 | P3 · Day 12 |
| RFC 7662 | Token Introspection | 资源服务器在线验证 token | P3 · Day 14 |
| RFC 7009 | Token Revocation | 主动吊销 token 的标准端点 | P3 · Day 14 |
| RFC 8252 | OAuth for Native Apps | 移动 / 桌面 App 的 OAuth 最佳实践 | P3 · Day 12 |
| RFC 8628 | Device Code Flow | 电视 / 打印机 / CLI 的 OAuth | P3 · Day 13 |
| RFC 8693 | Token Exchange | 跨域 token 换发,零信任常用 | P3 · Day 13 |
| RFC 9068 | JWT Profile for Access Tokens | 把 Access Token 标准化为 JWT 的规范 | P3 · Day 14 |
| RFC 9449 | DPoP | Sender-Constrained Token,解决 Bearer 被偷的问题 | P3 · Day 15 |
| RFC 6819 | OAuth Threat Model | OAuth 安全模型,Day 16 必读 | P3 · Day 16 |
| OIDC Core 1.0 | OpenID Connect Core | OAuth 之上的认证层 | P4 · Day 17 |
| RFC 7591 | Dynamic Client Registration | OIDC 客户端动态注册 | P4 · Day 18 |
| SAML 2.0 | OASIS SAML Core | 企业 SSO 的老牌协议 | P4 · Day 20 |
| RFC 7644 | SCIM 2.0 | 跨系统的用户 / 组同步标准 | P4 · Day 21 |
核心概念对照表
| 概念 | 含义 | 使用场景 | 阶段 |
|---|---|---|---|
| AuthN vs AuthZ | 认证 = 你是谁;授权 = 你能做什么 | 任何登录系统的设计第一步:分清这两件事 | P1 · Day 1 |
| Session vs Token | 状态在服务端 (Session) 还是在客户端 (JWT) | 选型决定吊销 / 扩展性 / 安全性的取舍 | P1-P2 · Day 4 / 6 |
| OAuth 2.0 vs OIDC | OAuth 授权(拿 Access Token),OIDC 认证(拿 ID Token) | "用 X 登录" = OIDC;"调 X 的 API" = OAuth | P3-P4 · Day 10 / 17 |
| Access vs Refresh Token | 短命的资源凭证 vs 长命的换发凭证 | 权衡安全性与用户体验的核心机制 | P3 · Day 14 |
| Authorization Code vs Implicit | Code Flow 走后端换 token;Implicit 直接给前端 token (已废弃) | 新项目一律用 Code + PKCE | P3 · Day 11 / 12 |
| Bearer vs DPoP | Bearer "凭票即用";DPoP 把 token 绑定到客户端密钥 | 高安全场景 / 公开客户端用 DPoP | P3 · Day 15 |
| OIDC vs SAML | OIDC JSON + REST,年轻;SAML XML,企业老协议 | 面向 C 端用 OIDC;面向大企业 IT 部门可能要 SAML | P4 · Day 17 / 20 |
| RBAC vs ABAC vs ReBAC | 角色 / 属性 / 关系 三种授权建模思路 | 后台管理 → RBAC;规则复杂 → ABAC;资源型 → ReBAC | P5 · Day 22-24 |
| PDP / PEP / PIP | 策略决策点 / 执行点 / 信息点(XACML 架构) | 策略引擎部署架构的标准术语 | P5 · Day 23 |
| API Key 签名 vs OAuth | 签名认证用对称密钥 + HMAC,OAuth 走 token 体系 | 云厂商 OpenAPI 多用签名;SaaS 多用 OAuth | P6 · Day 26 |
| mTLS vs Bearer | mTLS 在传输层互验证书;Bearer 在应用层带 token | 服务间通信首选 mTLS;公网 API 用 Bearer | P6 · Day 28 |
| SSO vs Federation | SSO 是"一次登录处处用",Federation 是"跨域信任建立" | SSO 多用 OIDC / SAML;Federation 多用 OIDC + IdP | P4 · Day 20 |
学习资源
经典论文与规范
OAuth 2.0 Security BCP
draft-ietf-oauth-security-topics——OAuth 安全的现代版"圣经",比 RFC 6819 更新。Day 15 / Day 16 必读。
Google Zanzibar 论文
"Consistent, Global Authorization System"——ReBAC 的祖师爷论文,现代权限系统(SpiceDB / OpenFGA)都是它的实现。Day 24 精读。
BeyondCorp 系列
Google 零信任架构 6 篇论文,从理念到落地。Day 29 的核心参考。
OAuth / OIDC Spec 全集
oauth.net/2/ 与 openid.net/specs/ 是规范权威入口,配合 RFC 速查表使用。
推荐书籍
- OAuth 2 in Action — Justin Richer / Antonio Sanso · OAuth 入门最系统的书,Manning 出版
- API Security in Action — Neil Madden · 后端 API 安全的全景图,覆盖 OAuth / JWT / mTLS / 容量限制
- Solving Identity Management in Modern Applications — Yvonne Wilson · 偏企业 IAM 视角,SAML / OIDC / SCIM 都讲
- Zero Trust Networks — Evan Gilman / Doug Barth · 零信任架构的实操指南
- 白帽子讲 Web 安全 — 吴翰清 · 国内 Web 安全入门经典,Phase 1 的中文补充读物
Go 生态选型
ory/hydra
Go 写的 OAuth 2.0 / OIDC 服务器,CNCF 项目,生产可用。Day 30 实战核心组件。
ory/kratos
用户管理 / 注册 / 登录 / MFA 一站式后端,搭配 Hydra 形成完整 IAM。
casbin/casbin
Go 最流行的访问控制库,支持 RBAC / ABAC / RESTful,配置即模型。
openfga / spicedb
Zanzibar 的开源实现,资源级权限的现代选择。
golang-jwt/jwt v5
Go 最常用的 JWT 库;JWS / JWE 用 go-jose/go-jose 更完整。
golang.org/x/oauth2
官方 OAuth 2.0 客户端实现,对接 GitHub / Google / 飞书等开放平台标配。
coreos/go-oidc
Go 里最成熟的 OIDC RP 实现,ID Token 验证 / Discovery 一把梭。
open-policy-agent/opa
通用策略引擎,Rego 语言写策略,K8s 准入控制 / 微服务授权都用它。
spiffe / spire
服务身份框架,Service Mesh 与零信任的基础设施。
参考开放平台(拆解学习)
Go 代码骨架速查
JWT 签发与校验(Day 9)
claims := jwt.MapClaims{
"sub": userID,
"aud": "openapi.example.com",
"exp": time.Now().Add(15 * time.Minute).Unix(),
"iat": time.Now().Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
signed, _ := token.SignedString(privateKey)
// 校验时一定要 explicit 指定算法,避免 alg 混淆攻击
parsed, err := jwt.Parse(signed, func(t *jwt.Token) (any, error) {
if t.Method != jwt.SigningMethodRS256 {
return nil, errors.New("unexpected alg")
}
return publicKey, nil
})
OAuth 2.0 客户端(Day 11)
cfg := &oauth2.Config{
ClientID: os.Getenv("CLIENT_ID"),
ClientSecret: os.Getenv("CLIENT_SECRET"),
RedirectURL: "https://app.example.com/callback",
Scopes: []string{"openid", "contact:read"},
Endpoint: myplatform.Endpoint,
}
// 1) 生成 state + PKCE,跳到授权页
state := randomString(32)
verifier := oauth2.GenerateVerifier()
url := cfg.AuthCodeURL(state, oauth2.S256ChallengeOption(verifier))
// 2) 回调里换 token
tok, err := cfg.Exchange(ctx, code, oauth2.VerifierOption(verifier))
Casbin RBAC 授权(Day 25)
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 中间件里检查权限
ok, _ := e.Enforce(userID, "/api/v1/contacts", "GET")
if !ok {
c.AbortWithStatus(http.StatusForbidden)
return
}
HMAC 签名验证(Day 26)
mac := hmac.New(sha256.New, []byte(appSecret))
mac.Write([]byte(timestamp + "\n" + nonce + "\n" + string(body)))
expected := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(expected), []byte(receivedSig)) {
return errors.New("invalid signature")
}
// 务必检查 timestamp 在 ±5 分钟内,防重放
学习方法建议
跟 RFC 走
OAuth / OIDC 的中文博客质量参差不齐,很多结论已过时(比如还在推 Implicit Flow)。每天最后 15 分钟对着 RFC 复核一遍今天的主题。
画时序图说服自己
每个流程都用 Mermaid / Excalidraw 画一遍时序图。搞清楚每条消息里"谁把什么发给谁、为什么需要它",比读十篇博客有效。
同时学攻击面
学每个机制时同步学它的攻击方式:JWT 学 alg 混淆,OAuth 学 Mix-up,Cookie 学 CSRF。安全感来自理解威胁模型,不来自"听说安全"。
自己实现一遍
读完规范一定要写 Go 代码。最小 OAuth Server + 最小 Client 走完整 Code Flow,能学到所有文章都没讲的细节。
关注废弃与演进
Implicit Flow / ROPC / SMS OTP / 自签 JWT 加密——这些"还活着但不该用"的,要知道为什么被废弃、替代方案是什么。这是高级工程师的判断力来源。