3、身份认证与授权:认证与授权的区别、常见认证协议(OAuth2.0、SAML)、RBAC模型
好,咱们今天聊聊身份认证和授权。这两个词经常被混着用,但说真的,它们完全是两码事。我见过不少团队在初期设计时没分清,结果后面改得焦头烂额。
3.1 认证 vs 授权:别搞混了
认证(Authentication),说白了就是「你是谁?」。你拿出身份证,系统验证一下,嗯,是你本人。
授权(Authorization),问的是「你能干什么?」。你进了门,但有些房间你不能进,有些文件你不能看。
我举个例子你就明白了。你去酒店办入住,前台看了你的身份证——这是认证。然后前台给你房卡,你只能刷开自己的房间,刷不开总统套房——这是授权。
核心区别一句话:
- 认证:验证身份(你是谁?)
- 授权:赋予权限(你能做什么?)
认证在前,授权在后。没有认证,授权就是空中楼阁。
我在项目中遇到过一种典型错误:有人把用户的角色信息直接塞进 JWT 的 payload 里,然后前端拿着这个 token 去判断用户能不能操作某个按钮。嗯,这其实只做了认证,授权完全依赖客户端。你想想看,客户端是可以被篡改的。正确的做法是,后端每次收到请求,都要重新校验用户的权限。
3.2 常见认证协议:OAuth2.0 和 SAML
聊完概念,咱们看看实际工作中最常用的两个协议。
3.2.1 OAuth2.0:授权框架,不是认证协议
很多人一上来就说「OAuth2.0 是认证协议」。其实不对。OAuth2.0 本质上是授权框架。它解决的是「我允许第三方应用访问我的资源,但我不给它我的密码」这个问题。
举个例子。你用微信登录某个小游戏。小游戏想知道你的微信昵称和头像,但你不想把微信密码给它。这时候 OAuth2.0 就派上用场了。
流程大致是这样的:
- 小游戏把你重定向到微信的授权页面
- 你在微信上确认「我同意小游戏获取我的昵称和头像」
- 微信给小游戏一个授权码(Authorization Code)
- 小游戏拿着这个授权码,去微信的后台换一个 Access Token
- 小游戏用 Access Token 去微信的 API 获取你的信息
你看,整个过程你的密码从来没给过小游戏。这就是 OAuth2.0 的精髓。
我个人习惯:在微服务架构中,API 网关统一处理 OAuth2.0 的 token 校验。每个微服务只管自己的业务逻辑,不用关心 token 怎么来的。这样职责清晰,出了问题也好排查。
OAuth2.0 有四种授权模式,最常用的是授权码模式(Authorization Code)。其他三种——隐式模式、密码模式、客户端凭证模式——各有适用场景,但安全风险也各不相同。我建议你优先用授权码模式,配合 PKCE(Proof Key for Code Exchange),安全性更高。
3.2.2 SAML:企业级的老大哥
SAML(Security Assertion Markup Language)比 OAuth2.0 出现得更早,主要用在企业级单点登录(SSO)场景。它基于 XML,传输的是断言(Assertion),而不是 token。
你想想看,一个大型企业可能有几十个内部系统:OA、CRM、ERP、HR……每个系统都让员工注册一遍账号密码,那不得疯掉?SAML 就是解决这个问题的。
它的核心思想是:有一个身份提供者(IdP,比如公司的统一认证中心),所有系统都信任它。员工登录一次 IdP,就能访问所有信任它的系统。
流程大概是:
- 你访问公司内部的 CRM 系统
- CRM 发现你没登录,把你重定向到公司的 IdP
- 你在 IdP 输入一次账号密码(或者已经登录了,直接跳过)
- IdP 生成一个 SAML 断言,发回给 CRM
- CRM 验证断言,确认是你本人,然后让你进去
我曾经踩过一个坑:SAML 断言是有时效的,默认可能只有几分钟。有一次我们对接一个老旧的第三方系统,对方把断言的有效期设成了 24 小时。结果有人离职后,他的 SAML 断言还能用一整天。嗯,从那以后我要求所有 SAML 断言的有效期不超过 5 分钟,并且必须配合 Session 超时机制。
OAuth2.0 和 SAML 怎么选?我个人建议:
- 如果是互联网应用、移动端、第三方授权场景,优先选 OAuth2.0
- 如果是企业内部系统、需要跨域 SSO、有现成的企业级 IdP,选 SAML
- 现在很多场景两者结合使用,比如用 SAML 做认证,用 OAuth2.0 做授权
3.3 RBAC 模型:权限管理的基石
好,聊完认证和授权协议,咱们看看授权模型。RBAC(Role-Based Access Control,基于角色的访问控制)是目前最主流的权限管理模型。
它的核心思想很简单:用户不直接拥有权限,而是通过角色来获得权限。
你想想看,一个公司有几百号人,如果每个人单独配置权限,那管理员得累死。但如果你把权限打包成角色——比如「管理员」、「编辑」、「访客」——然后把角色分配给用户,管理起来就轻松多了。
RBAC 有三个核心要素:
- 用户(User):系统的操作者
- 角色(Role):权限的集合,比如「管理员」
- 权限(Permission):对某个资源的操作,比如「删除文章」
它们的关系是:用户 → 角色 → 权限。用户通过角色间接获得权限。
举个例子:
| 用户 | 角色 | 权限 |
|---|---|---|
| 张三 | 管理员 | 创建文章、编辑文章、删除文章、管理用户 |
| 李四 | 编辑 | 创建文章、编辑文章 |
| 王五 | 访客 | 查看文章 |
你看,张三能删除文章,李四不能。因为「删除文章」这个权限只绑在了「管理员」角色上。
RBAC 的好处:
- 简化管理:新增一个岗位,只需要创建角色并分配权限,不用一个个改用户
- 职责分离:不同角色有不同的权限,避免越权操作
- 审计方便:谁有什么角色,角色有什么权限,一目了然
实际项目中,RBAC 还有几个变种:
- RBAC0:基础模型,就是上面说的用户-角色-权限
- RBAC1:引入角色继承,比如「超级管理员」继承「管理员」的所有权限
- RBAC2:引入约束,比如一个人不能同时拥有「出纳」和「会计」角色(职责分离)
- RBAC3:RBAC1 + RBAC2 的组合
我建议你从 RBAC0 开始,够用就行。别一开始就搞复杂的继承和约束,容易把自己绕进去。等业务复杂了,再逐步升级。
避坑指南:我曾经在一个项目中,把权限粒度设计到了按钮级别。结果权限配置表膨胀到几千行,每次上线都要花半天时间核对权限。后来我学乖了:权限粒度控制在「页面」或「功能模块」级别就够了。按钮级别的权限,用前端条件渲染处理,不要塞进后端权限模型里。
最后总结一下:认证是门禁卡,授权是门禁卡能刷开哪些门。OAuth2.0 适合互联网场景,SAML 适合企业级 SSO。RBAC 是权限管理最实用的模型,从简单开始,别过度设计。
嗯,这一章就到这里。下一章咱们聊聊会话管理和 Token 的安全存储,那也是个容易踩坑的地方。