2、身份认证与访问控制:多因素认证(MFA)、单点登录(SSO)、OAuth 2.0与OIDC协议、JWT令牌安全
身份认证和访问控制,说白了就是回答两个问题:「你是谁?」和「你能干什么?」。很多公司在这上面栽过跟头,我也见过不少。今天咱们就把这块的核心技术拆开揉碎了讲清楚。
2.1 多因素认证(MFA)——别只靠一个密码
密码这东西,太容易被攻破了。弱口令、撞库、钓鱼……我见过最夸张的一次,某公司全员用「123456」当密码,安全审计直接给了个不及格。
MFA 的核心逻辑:至少使用两种不同类型的认证因素。
| 因素类型 | 举例 | 安全性 |
|---|---|---|
| 知识因素(你知道的) | 密码、PIN码 | 低(易泄露) |
| 持有因素(你有的) | 手机、硬件令牌 | 中 |
| 固有因素(你是的) | 指纹、人脸 | 高 |
我在项目中遇到过一家金融客户,强制全员使用「密码 + 硬件令牌」双因素。结果运维人员嫌麻烦,把令牌贴在了显示器上……嗯,安全策略再好,人也永远是短板。
2.2 单点登录(SSO)——一次登录,到处跑
SSO 解决的是「密码疲劳」问题。用户不用在每个系统都输一遍密码,体验好,安全风险也降低了。
SSO 的典型流程:
- 用户访问应用 A,未登录,被重定向到身份提供者(IdP)。
- 用户在 IdP 登录(可能触发 MFA)。
- IdP 生成一个令牌(如 SAML 断言或 OIDC ID ),返回给应用 A。
- 应用 A 验证令牌,建立本地会话。
- 用户再访问应用 B,应用 B 发现已有 IdP 会话,直接获取令牌,无需再次登录。
我曾经帮一家电商公司做 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) | 服务间通信(无用户参与) | 低 |
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 的最佳实践
- 使用短生命周期的 Access (比如 15 分钟),配合长生命周期的 Refresh 。
- Refresh 必须做轮换:每次使用后颁发新的 Refresh ,旧的立即失效。
- 不要在客户端存储敏感信息:JWT 的 Payload 只是 Base64 编码,不是加密。
- 使用黑名单或版本号:当用户注销或权限变更时,能让旧令牌立即失效。
2.5 知识体系总览
下面这张图,把本章的核心知识点串起来了。你可以把它当作一张「身份认证与访问控制」的思维导图。
这张图里,MFA 是基础防线,SSO 是体验优化,OAuth 2.0 和 OIDC 是协议标准,JWT 是令牌载体。它们环环相扣,缺一不可。