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 就派上用场了。

流程大致是这样的:

  1. 小游戏把你重定向到微信的授权页面
  2. 你在微信上确认「我同意小游戏获取我的昵称和头像」
  3. 微信给小游戏一个授权码(Authorization Code)
  4. 小游戏拿着这个授权码,去微信的后台换一个 Access Token
  5. 小游戏用 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,就能访问所有信任它的系统。

流程大概是:

  1. 你访问公司内部的 CRM 系统
  2. CRM 发现你没登录,把你重定向到公司的 IdP
  3. 你在 IdP 输入一次账号密码(或者已经登录了,直接跳过)
  4. IdP 生成一个 SAML 断言,发回给 CRM
  5. 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 的安全存储,那也是个容易踩坑的地方。