跳转到内容

认证与授权

认证(authentication)回答"你是谁",授权(authorization)回答"你能做什么"——两件事必须分开做。本章讲会话与令牌、OAuth 2.0 / OIDC、访问控制模型,以及常见的实现错误(→ Web 安全)。

  • 存储:慢哈希 + 盐(Argon2id/bcrypt,→ 哈希函数与消息认证);
  • 传输:只在 HTTPS 上(→ TLS 与 HTTPS);
  • 失败:登录失败信息统一("用户名或密码错误"——别泄露哪个对)、限速与锁定(防爆破)。

多因素 = 知道的(密码)+ 拥有的(设备/令牌)+ 是的(生物特征)——密码泄露不再等于账号沦陷:

  • TOTP(时间一次性密码):手机计算器应用,比 SMS 强(SIM 劫持是 SMS 的死穴);
  • FIDO2/WebAuthn:设备密钥对 + 挑战-响应——抗钓鱼(域绑定,假站点拿不到有效签名),是现代默认;
  • 恢复码:MFA 的逃生通道——存下来(加密),别当第二密码。

登录后的"你是谁"证明有两种形态:

服务端会话(session)无状态令牌(JWT)
状态服务端存(session store)全部编码进令牌(签名保护)
吊销删服务端记录即可难(等到过期/黑名单)
体积小 ID大(含 claims)
扩展需共享 store无需(验签即可)

JWT 不等于安全,密钥管理与过期才是重点:

  • 短过期 + 刷新令牌:access token 分钟级,refresh token 长期且可吊销;
  • 签名算法别让客户端选(alg: none 攻击、HS/RS 混淆攻击——历史漏洞的来源);
  • 别放敏感数据:JWT 是 base64 编码不是加密——payload 谁都能读;
  • 吊销难题:无状态令牌"签发即有效到过期"——关键操作(改密、注销)要服务端会话或黑名单配合。

OAuth 是授权协议,OIDC 才是认证——最常见的混淆:

  • OAuth 2.0:授权委派("允许应用 A 访问我在服务 B 的数据,但不给它密码")——访问令牌代表被授予的权限;
  • OIDC(OpenID Connect,OAuth 之上的层):认证("这个用户是谁")——ID 令牌(JWT)携带身份断言。

Web 应用的标准流程:

① 应用把你引到身份提供方(IdP):"我要访问你的资料"
② 你在 IdP 登录并同意
③ IdP 重定向回应用,带一次性授权码
④ 应用后端拿授权码 + 客户端密钥换令牌
⑤ 后续请求带访问令牌

授权码在服务端换令牌(第④步)是安全根:令牌不经过前端;PKCE(扩展)让无后端的移动/SPA 也能安全(防拦截授权码)。

  • 隐式流程(implicit)已废弃:令牌走前端 URL,历史漏洞来源;
  • 令牌当会话用:access token 短期,长期身份用 refresh + OIDC 会话;
  • scope 不收敛:授权范围最小化(→ 最小权限,见下)。
模型结构适用
ACL资源 → 允许的主体系简单、文件系统
RBAC用户 → 角色 → 权限组织结构清晰(多数企业系统)
ABAC属性条件(用户/资源/环境)细粒度、动态("同一部门且工作时间")
  • RBAC 是企业默认:角色爆炸(几百个角色)时是负债——回到"职责分离"的原则设计角色;
  • ABAC(策略引擎:OPA 一类)表达细粒度规则,代价是策略的可审计性与调试难度;
  • 最小权限原则:所有访问控制的指导原则——默认拒绝、按需授予、定期回收。
  • IDOR(不安全的直接对象引用):/orders/12345 只查"是本人的"吗——每一层都校验授权,别信前端藏 URL;
  • 前端藏 ≠ 授权:隐藏按钮不是权限控制——服务端逐请求校验;
  • 垂直越权:普通用户调用管理员接口——权限校验在路由层强制。
  • 认证回答"你是谁",授权回答"你能做什么"——分开做、分开审
  • MFA 抗钓鱼选 FIDO2;恢复码要存好
  • 会话吊销容易但需共享状态;JWT 吊销难——短过期 + 刷新令牌;JWT 是编码不是加密
  • OAuth 是授权协议,OIDC 才是认证;授权码 + PKCE 是标准流程
  • JWT 不等于安全,密钥管理与过期才是重点;最小权限是所有访问控制的指导原则;IDOR 的根源是逐层不校验