身份校验基础:认证与授权,你真的分得清吗?

做安全这么多年,我见过太多团队把「认证」和「授权」混为一谈。有一次评审代码,开发同学说「我们已经做了登录校验,权限肯定没问题」——结果用户登录后能看到所有人的订单数据。嗯,这就是典型的认证过关、授权失守。

这一节,咱们先把这两个概念掰扯清楚,再聊聊主流的身份校验协议。你想想看,如果连基础都没打牢,后面做安全刷新方案很容易翻车。

身份认证 vs 授权:一对「双胞胎」但性格完全不同

说白了,身份认证是回答「你是谁?」,授权是回答「你能干什么?」。我习惯用一个生活场景来理解:

  • 认证:你进公司大门刷工卡,门禁系统确认你是员工张三。
  • 授权:你走到财务部门口,门禁系统发现张三没有财务权限,拒绝进入。

你看,认证通过不代表授权通过。我在项目中遇到过好几次这样的坑:系统只做了登录认证,没做细粒度授权,结果普通用户能访问管理后台的 API。这其实是个很危险的设计漏洞。

维度 身份认证 (Authentication) 授权 (Authorization)
核心问题 你是谁? 你能做什么?
常用机制 密码、生物识别、OTP、证书 RBAC、ABAC、ACL、权限令牌
典型凭证 Session ID、JWT (身份声明) Access Token、权限 Scope
失败后果 无法登录系统 越权操作、数据泄露
执行顺序 先认证,后授权 依赖认证结果

核心原则:认证是授权的「前置条件」,但认证通过绝不等于授权通过。每次请求都必须独立校验授权,不能因为用户已经登录就放行。

常见身份校验协议:OAuth 2.0、SAML、OpenID Connect

现在主流的身份校验协议有三个:OAuth 2.0、SAML 和 OpenID Connect。它们解决的问题不同,适用场景也不同。我按自己的理解给你拆开讲。

OAuth 2.0:授权框架,不是认证协议

很多人以为 OAuth 2.0 是做登录的,其实它是个授权框架。它的核心场景是:用户允许第三方应用访问自己在某服务上的资源,但不用把密码交给第三方。

举个例子:你用「登录」来使用某个笔记 App。不会把密码给笔记 App,而是给 App 一个 Access Token,这个 Token 只允许 App 读取你的昵称和头像,不能发朋友圈。这就是 OAuth 2.0 的授权委托思想。

OAuth 2.0 定义了四种授权模式:

  • 授权码模式 (Authorization Code):最安全,用于有后端的 Web 应用。流程中会返回一个临时授权码,后端再用授权码换取 Token。
  • 隐式模式 (Implicit):已废弃,因为 Token 直接暴露在 URL 中,不安全。
  • 密码模式 (Resource Owner Password Credentials):用户直接把密码给第三方,不推荐使用。
  • 客户端凭证模式 (Client Credentials):用于服务间通信,没有用户参与。

避坑提醒:我曾经见过一个项目,为了省事直接用了密码模式,用户的密码明文存储在第三方应用的日志里。这非常危险。除非是绝对信任的第一方应用,否则不要用密码模式。

SAML:企业级单点登录的老大哥

SAML(Security Assertion Markup Language)是基于 XML 的协议,主要用在企业内部的单点登录(SSO)场景。它的核心是「断言」——身份提供者(IdP)向服务提供者(SP)断言:这个用户已经认证过了,他的身份信息如下。

SAML 的典型流程:

  1. 用户访问企业内部的某个应用(SP)。
  2. 应用发现用户未登录,重定向到企业身份服务器(IdP)。
  3. 用户在 IdP 输入一次密码,完成认证。
  4. IdP 生成一个 SAML 断言(XML 格式),通过浏览器 POST 回应用。
  5. 应用解析断言,确认用户身份,建立本地会话。

SAML 的优势是成熟、安全,适合大型企业。但它的缺点也很明显:XML 解析复杂,配置繁琐,移动端支持不好。我做过一个项目,光是调试 SAML 的签名和断言格式就花了两天。

OpenID Connect:OAuth 2.0 的「认证升级版」

OpenID Connect(OIDC)是在 OAuth 2.0 之上加了一层身份认证层。它解决了 OAuth 2.0 的一个核心问题:OAuth 2.0 只给 Token,不给用户身份信息。而 OIDC 通过 ID Token(JWT 格式)直接告诉你是谁。

OIDC 的核心概念:

  • ID Token:JWT 格式,包含用户身份信息(sub、name、email 等)。
  • UserInfo Endpoint:用 Access Token 换取更详细的用户信息。
  • Scope:openid 是必须的 scope,表示这是一个 OIDC 请求。

现在大部分「第三方登录」都基于 OIDC 实现。它比 SAML 轻量,比纯 OAuth 2.0 多了身份认证能力,是移动端和现代 Web 应用的首选。

我的建议:新项目做 SSO 或第三方登录,优先考虑 OpenID Connect。它基于 JSON 和 JWT,解析简单,生态好。SAML 留给那些必须兼容老系统的企业场景。

三种协议对比:一张表说清楚

维度 OAuth 2.0 SAML OpenID Connect
本质 授权框架 认证协议 认证协议(基于 OAuth 2.0)
数据格式 JSON XML JSON (JWT)
核心凭证 Access Token SAML Assertion ID Token + Access Token
适用场景 API 授权、资源委托 企业 SSO、老系统集成 第三方登录、移动端 SSO
复杂度 中等 高 低-中等
移动端支持 好 差 好

核心逻辑关系图

下面这张图展示了认证、授权以及三种协议之间的关系。你可以把它当作本章的知识骨架。

身份校验核心逻辑关系图 身份校验核心逻辑关系 身份认证 授权 先认证,后授权 OAuth 2.0 (授权框架) SAML (认证协议) OpenID Connect (认证协议) 提供授权 提供认证 提供认证+授权 说明: • OAuth 2.0 本身不提供身份认证,只提供授权委托。 • SAML 和 OpenID Connect 是认证协议,但 OIDC 基于 OAuth 2.0 构建。 • 实际项目中,OIDC 通常同时承担认证和授权两个角色。

小结:怎么选?

没有银弹。我个人的选择逻辑是这样的:

  • 如果是企业内部系统,需要对接 AD/LDAP,且已有 SAML 基础设施,继续用 SAML 没问题。
  • 如果是新项目、移动端、第三方登录,无脑选 OpenID Connect。
  • 如果只是服务间 API 授权,没有用户参与,用 OAuth 2.0 的客户端凭证模式就够了。

记住:认证和授权是两个独立的安全控制点。哪怕你用了最牛的协议,如果代码里没做授权校验,该泄露的数据一样会泄露。嗯,这一点怎么强调都不为过。