2、身份认证与访问控制:多因素认证(MFA)、单点登录(SSO)、OAuth 2.0与OIDC协议、JWT令牌安全

身份认证和访问控制,说白了就是回答两个问题:「你是谁?」和「你能干什么?」。很多公司在这上面栽过跟头,我也见过不少。今天咱们就把这块的核心技术拆开揉碎了讲清楚。

2.1 多因素认证(MFA)——别只靠一个密码

密码这东西,太容易被攻破了。弱口令、撞库、钓鱼……我见过最夸张的一次,某公司全员用「123456」当密码,安全审计直接给了个不及格。

MFA 的核心逻辑:至少使用两种不同类型的认证因素。

因素类型 举例 安全性
知识因素(你知道的) 密码、PIN码 低(易泄露)
持有因素(你有的) 手机、硬件令牌 中
固有因素(你是的) 指纹、人脸 高
我的建议:别只依赖短信验证码。SIM 卡换卡攻击太常见了。优先用 TOTP(基于时间的一次性密码)或硬件密钥(如 YubiKey)。

我在项目中遇到过一家金融客户,强制全员使用「密码 + 硬件令牌」双因素。结果运维人员嫌麻烦,把令牌贴在了显示器上……嗯,安全策略再好,人也永远是短板。

2.2 单点登录(SSO)——一次登录,到处跑

SSO 解决的是「密码疲劳」问题。用户不用在每个系统都输一遍密码,体验好,安全风险也降低了。

SSO 的典型流程:

  1. 用户访问应用 A,未登录,被重定向到身份提供者(IdP)。
  2. 用户在 IdP 登录(可能触发 MFA)。
  3. IdP 生成一个令牌(如 SAML 断言或 OIDC ID ),返回给应用 A。
  4. 应用 A 验证令牌,建立本地会话。
  5. 用户再访问应用 B,应用 B 发现已有 IdP 会话,直接获取令牌,无需再次登录。
注意:SSO 是双刃剑。一旦 IdP 被攻破,所有下游应用都会失守。所以 IdP 本身必须做最强的防护——MFA、异常检测、审计日志一个都不能少。

我曾经帮一家电商公司做 SSO 改造。他们之前每个子系统各自为政,光密码重置流程就有 5 套。统一到 SSO 后,IT 支持工单直接降了 40%。

2.3 OAuth 2.0 与 OIDC 协议——授权与认证的黄金搭档

很多人把 OAuth 2.0 和 OIDC 混为一谈。其实它们分工明确:

  • OAuth 2.0:负责授权。告诉系统「这个应用可以访问你的哪些资源」。
  • OIDC(OpenID Connect):在 OAuth 2.0 之上加了一层身份认证。告诉系统「这个用户是谁」。

说白了,OAuth 2.0 给钥匙,OIDC 给身份证。

OAuth 2.0 的四种授权模式

授权模式 适用场景 安全风险
授权码模式(Authorization Code) 有后端的 Web 应用 低(推荐)
隐式模式(Implicit) 纯前端应用(已不推荐) 高(令牌暴露在 URL 中)
密码模式(Resource Owner Password) 高度信任的第一方应用 中(需明文密码)
客户端模式(Client Credentials) 服务间通信(无用户参与) 低
避坑指南:我曾经见过一个团队在移动端用了隐式模式,Access 直接暴露在回调 URL 里。攻击者只要拿到手机日志,就能冒充用户。后来我帮他们改成了授权码模式 + PKCE(Proof Key for Code Exchange),才把漏洞堵上。

OIDC 的核心:ID

OIDC 在 OAuth 2.0 的基础上,增加了一个 ID (通常是 JWT 格式)。它包含了用户的身份信息,比如 sub(用户唯一标识)、name、email 等。

// 一个典型的 ID  载荷(Payload)
{
  "iss": "https://accounts.example.com",
  "sub": "1234567890",
  "aud": "client_id_123",
  "exp": 1718000000,
  "iat": 1717996400,
  "name": "张三",
  "email": "zhangsan@example.com"
}

你想想看,有了 ID ,应用就不需要再自己维护一套用户表了。认证的事,全交给 IdP 搞定。

2.4 JWT 令牌安全——别让令牌变成定时炸弹

JWT(JSON Web )是目前最流行的令牌格式。它自包含、跨语言、无状态,用起来确实方便。但方便不等于安全。

JWT 的结构:

Header.Payload.Signature

举个例子:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IuW8oOS4iSIsImlhdCI6MTUxNjIzOTAyMn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT 的常见安全陷阱

陷阱 后果 解决方案
签名算法未校验 攻击者可伪造任意令牌 强制使用 RS256/ES256,禁用 none 算法
密钥泄露 所有令牌可被伪造 定期轮换密钥,使用密钥管理服务(KMS)
令牌未设置过期时间 令牌永久有效 设置合理的 exp,配合 Refresh 使用
Payload 存放敏感信息 Base64 解码即可读取 JWT 默认不加密,敏感数据不要放 Payload
我曾经踩过的坑:有次做渗透测试,发现某系统 JWT 的签名算法是「none」。这意味着任何人都可以伪造任意身份的令牌。更离谱的是,开发团队说「我们以为默认就是安全的」。嗯,从那以后,我每次做 JWT 相关项目,第一件事就是检查签名算法配置。

JWT 的最佳实践

  • 使用短生命周期的 Access (比如 15 分钟),配合长生命周期的 Refresh 。
  • Refresh 必须做轮换:每次使用后颁发新的 Refresh ,旧的立即失效。
  • 不要在客户端存储敏感信息:JWT 的 Payload 只是 Base64 编码,不是加密。
  • 使用黑名单或版本号:当用户注销或权限变更时,能让旧令牌立即失效。

2.5 知识体系总览

下面这张图,把本章的核心知识点串起来了。你可以把它当作一张「身份认证与访问控制」的思维导图。

身份认证与访问控制知识体系 身份认证与访问控制 多因素认证 (MFA) 知识 + 持有 + 固有 单点登录 (SSO) 一次登录,访问所有 OAuth 2.0 授权 授权码 / 客户端 / PKCE JWT 令牌安全 签名校验 / 短生命周期 / 轮换 OIDC 身份认证 ID / UserInfo 端点

这张图里,MFA 是基础防线,SSO 是体验优化,OAuth 2.0 和 OIDC 是协议标准,JWT 是令牌载体。它们环环相扣,缺一不可。

一句话总结:认证是「证明你是谁」,授权是「决定你能做什么」。别搞混,也别偷懒。安全没有银弹,但把这套组合拳打好了,至少能挡住 90% 的常见攻击。