第1章:身份认证与访问控制

大家好,我是你们这堂课的老朋友。今天咱们聊聊安全架构里最基础、也最要命的一块——身份认证与访问控制。

说白了,就是两件事:「你是谁?」「你能干什么?」

我做了十几年安全架构,见过太多系统在这上面栽跟头。有的公司上了最牛的防火墙,结果内部一个弱口令就全完蛋。有的用了最复杂的算法,结果权限模型一团浆糊,普通员工能看到CEO的工资单。

嗯,咱们今天就把这块彻底捋清楚。

核心观点:认证是门锁,授权是房间里的权限。门锁再结实,房间里东西乱放也不行。反过来,房间管理得再好,门锁一捅就开,也是白搭。

身份认证与访问控制 认证机制 密码认证 多因素认证 生物识别 授权模型 RBAC ABAC PBAC 会话与令牌 JWT OAuth 2.0 会话管理 三者缺一不可,共同构成安全防线

一、认证机制:你到底是谁?

认证,就是验证用户身份的过程。你想想看,如果连门都看不住,后面再好的权限设计也是白搭。

1. 密码认证

最古老、也最常用的方式。但我得说句实话——密码本身就是个妥协方案

我在项目中遇到过一家公司,密码策略是「8位以上,必须包含大小写、数字、特殊字符」。听起来很安全对吧?结果员工全把密码贴在显示器上。为什么?因为记不住啊。

我的建议:别把密码策略搞得太变态。与其要求「P@ssw0rd!2024」这种反人类的密码,不如鼓励用户用「正确-马-电池-订书机」这种长短语。长度才是密码安全的第一要素。

存储密码时,记住一个铁律:永远不要明文存储。要用加盐的哈希算法,比如 bcrypt、scrypt 或 Argon2。

// 错误示范(我见过太多人这么干了)
String password = request.getParameter("password");
saveToDatabase(password);  // 明文存储!找死!

// 正确做法
String salt = generateSalt();
String hashedPassword = bcrypt.hash(password, salt);
saveToDatabase(hashedPassword, salt);

警告:MD5 和 SHA-1 已经不够用了。别再用它们做密码哈希。我曾经审计过一个项目,他们用 MD5 哈希密码,连盐都没加。结果数据库泄露后,彩虹表一跑,80% 的密码直接还原。

2. 多因素认证(MFA)

光有密码不够。为什么?因为密码太容易被偷了。钓鱼、撞库、键盘记录器……手段多得很。

多因素认证,说白了就是「你知道的 + 你拥有的 + 你本身的」至少组合两种。

  • 你知道的:密码、PIN码
  • 你拥有的:手机(短信验证码)、硬件密钥(YubiKey)、TOTP 应用(Google Authenticator)
  • 你本身的:指纹、人脸、虹膜

我个人习惯是:所有面向外网的系统,强制开启 MFA。内网系统至少也要支持可选。别嫌麻烦,真出了事更麻烦。

避坑指南:我曾经帮一家金融公司做安全评估。他们上了短信验证码做 MFA,看起来没问题。但后来发现,攻击者通过 SIM 卡交换攻击,直接把验证码劫持了。从那以后,我强烈推荐用 TOTP 或硬件密钥,而不是短信。

3. 生物识别

指纹、人脸、声纹……这些听起来很酷,但也不是万能的。

生物识别的最大问题是:它不可撤销。密码泄露了可以改,指纹泄露了你能换手指吗?

所以我的建议是:生物识别适合做辅助认证,或者低安全场景的便捷登录。真正的高安全场景,还是得靠密码 + 硬件密钥的组合。

二、授权模型:你能干什么?

认证完了,接下来就是授权。说白了,就是「你进来了,但你能碰哪些东西?」

1. RBAC(基于角色的访问控制)

这是最经典的模型。把权限打包成「角色」,然后把角色分配给用户。

比如:管理员、编辑、普通用户。每个角色有一组权限。用户是什么角色,就有什么权限。

我的经验:RBAC 适合权限结构相对稳定的系统。我在做电商平台时,就用 RBAC 管理后台权限。运营、客服、财务各司其职,清晰明了。

但 RBAC 有个问题——粒度不够细。比如「编辑」角色能编辑所有文章,但你可能只想让某个编辑只能编辑科技类的文章。这时候就需要 ABAC 了。

2. ABAC(基于属性的访问控制)

ABAC 不看角色,看属性。用户的属性、资源的属性、环境的属性,组合起来做决策。

举个例子:

  • 用户属性:部门=技术部,职级=高级
  • 资源属性:文档分类=技术文档,密级=内部
  • 环境属性:时间=工作时间,IP=公司内网

策略可以写成:「允许技术部高级员工在工作时间从内网访问内部技术文档」。

你看,比 RBAC 灵活多了吧?但代价是——策略管理复杂。属性一多,策略就乱。我见过一个项目,ABAC 策略写了上千条,最后没人敢改。

3. PBAC(基于策略的访问控制)

PBAC 是 ABAC 的进化版。它把权限决策抽象成「策略引擎」,用统一的语言(比如 XACML 或 ALFA)来描述策略。

说白了,PBAC 就是给 ABAC 加了一层「策略管理框架」。让策略的编写、测试、审计都变得规范。

模型 优点 缺点 适用场景
RBAC 简单、直观、易管理 粒度粗,灵活性差 权限结构稳定的系统
ABAC 粒度细,灵活性强 策略复杂,管理成本高 需要细粒度控制的系统
PBAC 标准化、可审计、可扩展 实现复杂,学习曲线陡 大型企业级系统

三、会话管理与令牌机制

认证通过了,授权也配好了。但用户每次请求都要重新认证吗?当然不。这时候就需要会话管理和令牌机制了。

1. 会话管理

传统的会话管理,就是服务端存一个 session,客户端存一个 session ID(通常放在 cookie 里)。

但这种方式有个问题——服务端有状态。如果做负载均衡,session 得共享,不然用户请求打到不同服务器就掉线了。

注意:我曾经遇到过一个项目,session 存在本地内存里,没做共享。结果上线后用户频繁掉线,排查了半天才发现是负载均衡的问题。后来改用 Redis 做 session 共享才解决。

2. JWT(JSON Web Token)

JWT 解决了「有状态」的问题。它把用户信息加密后放在 token 里,服务端不需要存 session,直接验证 token 就行。

一个 JWT 长这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

它由三部分组成:Header、Payload、Signature。用 Base64 编码,最后用密钥签名。

但 JWT 也有坑:

  • 无法撤销:token 发出去了,除非等它过期,否则没法让它失效。所以过期时间要设短一点。
  • Payload 是明文:别把密码、信用卡号放进去。Base64 不是加密,是编码。

我的习惯:JWT 的过期时间设 15-30 分钟。配合 refresh token 使用。这样即使 token 泄露,损失也有限。

3. OAuth 2.0

OAuth 2.0 不是认证协议,是授权协议。它解决的是「第三方应用如何安全地访问用户资源」的问题。

比如你用微信登录某个网站,网站不会拿到你的微信密码,而是通过 OAuth 2.0 拿到一个临时的 access token,用这个 token 去获取你的基本信息。

OAuth 2.0 有四种授权模式:

  1. 授权码模式:最安全,适合有后端的应用
  2. 隐式模式:适合纯前端应用(现在不推荐了)
  3. 密码模式:直接拿用户名密码换 token(尽量别用)
  4. 客户端凭证模式:适合服务间调用

我个人建议:能用授权码模式就别用别的。隐式模式已经被 OAuth 2.1 废弃了,密码模式说白了就是把密码交给第三方,风险太大。

总结一下:认证是基础,授权是核心,会话和令牌是桥梁。这三块做好了,系统的安全就有了八成把握。剩下的两成,靠的是持续的安全审计和应急响应。

嗯,今天就聊到这儿。内容不少,但都是干货。你回去可以看看自己负责的系统,这三块做得怎么样。有问题随时找我聊。


专注资料整理