4. 身份与访问管理(IAM):认证、授权、RBAC、ABAC、单点登录

身份与访问管理,简称IAM。说白了,它就是整个安全架构的大门。门锁不好,再坚固的墙也没用。我在过去几年参与过的安全审计里,超过一半的严重漏洞都出在身份管理上。不是密码泄露,就是权限过大,要不就是离职员工的账号还挂在系统上。

这一章,我会把IAM拆成几个核心模块来讲:认证、授权、以及两个主流的授权模型——RBAC和ABAC。最后聊聊单点登录,怎么让用户体验和安全都不掉队。

4.1 先搞清楚一件事:认证 vs 授权

很多新手会混淆这两个概念。我刚开始做项目时也犯过这错。

  • 认证(Authentication):证明“你是谁”。密码、指纹、人脸、OTP,都是在做这件事。
  • 授权(Authorization):确定“你能做什么”。登录成功不代表你能删数据库。那是另一道关卡。

一个典型流程是这样的:你先输密码(认证),系统确认你是管理员后,再检查你有没有“删除用户”的权限(授权)。两步缺一不可。

核心原则:认证在先,授权在后。绝不能用认证结果直接代替授权判断。

4.2 认证:不只有密码

密码认证,虽然古老但依然主流。不过,纯密码方案已经不够看了。我见过太多因为弱口令被拖库的案例。

现在业界的做法是多因素认证。别只依赖一样东西,至少组合两种:

  • 知识因素:密码、PIN码
  • 持有因素:手机、硬件Key、TOTP
  • 固有因素:指纹、人脸、虹膜

我个人习惯是:核心系统必须启用MFA。你可以让用户选择偏好,但至少要强制一个持有因素。比如密码+TOTP,这是成本低、兼容好的方案。

小提示:TOTP的密钥传输一定要走TLS。曾经有个项目把密钥明文写在了URL里,结果被中间人截获。嗯,那是我去帮忙救的火。

4.3 授权模型:RBAC 与 ABAC

授权模型是IAM的核心设计决策。选错了,后期改起来非常痛苦。我踩过这个坑。

4.3.1 基于角色的访问控制

RBAC,最经典的模型。它把权限打包成“角色”,再把角色分配给用户。用户-角色-权限,三层结构。

// 一个简化的RBAC数据模型示例
Role: "审计员"
  - Permission: "查看日志"
  - Permission: "导出报表"

User: "张三"
  - Role: "审计员"

RBAC的优点很明显:管理简单、容易理解。适合组织架构稳定的场景。比如企业内部系统、ERP、OA。

但它的短板也不小。如果你遇到“所有合同金额超过10万的订单,需要二级审批”这种需求,RBAC就吃力了。你得创建“普通审批员”和“高级审批员”两个角色,然后手动维护用户归属。角色数一多,就成了角色爆炸。

4.3.2 基于属性的访问控制

ABAC则灵活得多。它不靠角色,而是靠属性来做决策。属性来自四方面:

  • 用户属性:部门、职级、区域
  • 资源属性:文件密级、金额、创建时间
  • 环境属性:访问时间、IP段、设备类型
  • 操作属性:读、写、删除、导出

策略引擎根据一组规则,实时计算是否允许这次访问。比如:

策略: "财务部员工可以在工作时间读取金额小于10万的合同"
规则引擎判断:
  用户.部门 == "财务部" AND
  资源.金额 < 100000 AND
  环境.时间 IN [09:00-18:00] AND
  操作 == "读取"
  → 允许

灵活是高,但代价也不小。策略多了,维护难度和性能开销都会上去。我记得有一次帮客户调优ABAC引擎,规则到了200条后,每次鉴权都超500ms。最后不得不引入缓存和规则预编译。

避坑指南:我曾经在一个项目中直接用RBAC硬撑ABAC的场景。结果角色从20个膨胀到150个,管理员维护到崩溃。最后还是重构了。选模型时,先评估你未来一年的业务复杂度,别只看眼前。

4.4 RBAC vs ABAC:怎么选?

这里我给一个快速对比。你对照着看就行。

维度 RBAC ABAC
管理复杂度 低,角色清晰 高,策略易堆积
灵活性 低,动态场景吃力 高,支持细粒度规则
性能 快,缓存友好 视规则量而定
适用场景 组织架构稳定、职能固定 多维度、动态权限

我个人认为,绝大多数业务系统可以从RBAC起步。等到明确出现了“角色爆炸”或者“动态策略需求”,再局部引入ABAC。不要一开始就上全量ABAC,过度设计比没有设计更麻烦。

4.5 单点登录:一次登录,到处访问

SSO不是一种技术,而是一种模式。它让你用一个身份在多个系统间无缝切换。最常见的实现是OAuth 2.0 + OpenID Connect。

SSO的好处很明显:

  • 用户不用记一堆密码,体验提升
  • 密码只在IdP端集中管理,攻击面减少
  • 账号生命周期管理更集中,离职一个地方处理完

但SSO也有它的命门。如果IdP宕机,所有下游系统都受影响。还有,一旦IdP被攻破,攻击者就拿到了所有系统的入场券。

我的建议:SSO一定要配合MFA使用。IdP端做好熔断机制,比如本地缓存一个备用,在IdP不可用时降级为本地认证,至少保证核心功能可用。

4.5.1 OAuth 2.0 的授权码模式

最常用的流程是这个。我快速写一个典型的票据交换过程:

1. 用户访问App,App将其重定向到授权服务器
2. 用户登录并授权
3. 授权服务器返回授权码(code)到回调地址
4. App用授权码 + client_secret 换取 access_
5. App用access_请求资源服务器

注意,授权码是一次性的。别重复使用。

4.6 本章核心知识体系

下面的图,把整个IAM的核心链条和关系串起来了。你对照着理解。

身份与访问管理核心体系 用户 / 终端 认证 (AuthN) 授权 (AuthZ) RBAC 模型 ABAC 模型 单点登录 (SSO) 流程: 用户 → 认证 → 授权 → RBAC/ABAC 决策 → 访问资源

4.7 最佳实践与避坑

最后,我总结几条实战建议。这些是我在项目中亲身踩过、修补过的。

  • 认证和授权分离:别把身份信息和权限信息混在一个表里。各存各的,方便扩展。
  • 最小权限原则:给用户刚刚好的权限。多一点都不要。尤其是生产环境。
  • 定期审计权限:一个季度至少清理一次僵尸账号和过期权限。我曾经查过一个系统,有40%的账号是离职员工的。
  • SSO需要降级方案:IdP挂了,不能让用户卡死在门外。准备一个备用认证通道。
  • 记录鉴权日志:谁、什么时候、请求了什么资源、结果如何。存下来,出了事才好追溯。
最后一句:IAM不是一锤子买卖。上线只是开始,运维和持续改进才是常态。别想着一次搞定,要随着业务一起演进。