打开/关闭菜单
切换首选项菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

OAuth 2.1

✨寻星知识库——携手与您,寻觅群星。

OAuth 2.1 是一种用于授权的、开放的协议标准。例如,它可用于允许 微博 在服务端读取你阿里云盘上的照片,而无需向 微博 提供你的 阿里云盘用户名和密码或共享API令牌,并且在你发现 微博 抓取了你的所有私人照片时,提供一种标准化的方式来撤销访问权限。[1]

OAuth 2.1 是一项正在进行中的工作,旨在整合和简化 OAuth 2.0 中最常用的功能。[2]

自2012年OAuth 2.0(RFC 6749)首次发布以来,陆续有新的RFC发布,这些RFC对核心规范进行了功能上的增删,包括《原生应用的OAuth 2.0》(RFC 8252)、《代码交换证明密钥》(RFC 7636)、《基于浏览器的应用的OAuth》以及《OAuth 2.0安全最佳实践》。[2]

OAuth 2.1整合了后续规范中发布的变更,以简化核心文档,并废弃了一些被认为不安全的流程(如隐式授权)。[2]

与OAuth 2.0的主要区别[编辑 | 编辑源代码]

  1. 所有使用授权码流程的OAuth客户端必须启用PKCE[2]
    • 变更点:PKCE(代码交换证明密钥)从原本仅建议(特别是移动/原生应用使用)变为强制要求,适用范围扩展至所有采用授权码流程的客户端(包括Web应用)。
    • 原因:有效防御授权码拦截攻击。即使攻击者通过恶意软件或共享设备窃取授权code,若缺少合法客户端生成的code_verifier,仍无法兑换令牌。此举在客户端密钥泄露时仍能提供保护。OAuth 2.0仅对公开客户端建议使用PKCE。
  2. 重定向URI必须严格精确匹配
    • 变更点:授权服务器必须对注册的重定向URI与请求中的redirect_uri参数进行完全一致的大小写敏感字符串比对,禁止子域名匹配、路径追加或忽略大小写等宽松规则。
    • 原因:杜绝开放重定向攻击。若允许模糊匹配,攻击者可构造相似域名(如https://client.com.attacker.com)或路径(如https://client.com/evil)窃取令牌。精确匹配确保令牌仅返回至预先注册的可信端点。
  3. 隐式授权模式(response_type=token)被移除
    • 变更点:直接将访问令牌返回到URL片段中的隐式流程从核心规范中删除
    • 原因:该模式存在严重安全隐患——令牌会暴露于浏览器历史记录、服务器日志(通过Referer头)且易遭泄漏。替代方案是采用PKCE加固的授权码流程,仅通过code在后端兑换令牌。OAuth 2.0已弃用此模式,OAuth 2.1彻底移除。
  4. 资源所有者密码凭证模式被移除
    • 变更点:允许客户端直接收集用户账号密码并发送至授权服务器兑换令牌的流程从核心规范中删除
    • 原因:该模式极不安全——诱导用户向第三方应用输入密码(增加钓鱼风险)、密码可能被客户端留存,且违背OAuth"无需共享密码即可授权"的核心原则。现代替代方案是结合PKCE的授权码流程。OAuth 2.0已不推荐,OAuth 2.1彻底移除。
  5. 禁止在URI查询字符串中使用承载令牌
    • 变更点:明确禁止客户端在URL查询参数(如?access_token=...)中传递Bearer令牌。
    • 原因:URL常被服务器、代理或浏览器记录。查询字符串中的令牌可能长期留存于日志,导致未授权访问。规范要求令牌必须通过Authorization头(Bearer <token>)或(谨慎使用的)POST正文传递。OAuth 2.0建议避免,OAuth 2.1明文禁止。
  6. 公开客户端的刷新令牌必须满足发送方约束或单次使用
    • 变更点:颁发给公开客户端(无法安全存储密钥的应用,如移动/原生应用或SPA)的刷新令牌必须满足以下任一条件:
      • 发送方约束:通过DPoP(持有证明演示)或mTLS等机制绑定至特定客户端实例,使用时需验证密钥所有权。
      • 单次使用:每次刷新后立即失效,仅能兑换新访问令牌(可选包含新刷新令牌)。
    • 原因:大幅降低刷新令牌被盗的影响。若公开客户端的刷新令牌被窃(如通过恶意软件),攻击者无法在其他设备使用。发送方约束要求密钥验证,单次使用则缩短攻击窗口。OAuth 2.0对此要求较弱。
  7. 简化客户端类型定义
    • 变更点:公开客户端与机密客户端的区分更简洁
      • 机密客户端:能安全保密其凭证(如密钥或私钥),典型如服务端Web应用。
      • 公开客户端无法保密凭证(如浏览器应用或移动应用),本质上不具备有效的静态密钥。
    • 原因:明确安全预期。定义核心聚焦于客户端技术层面保护密钥的能力。OAuth 2.0的定义较复杂(如涉及"客户端认证"),易导致实现混淆。简化后直接关联如刷新令牌等安全要求(见第6点)。

总结

OAuth 2.1整合了OAuth 2.0多年实践中的安全最佳方案,核心改进包括:

  1. 剔除不安全流程:移除隐式和密码模式
  2. 强制关键防护:全面要求PKCE
  3. 强化校验机制:严格执行重定向URI精确匹配
  4. 降低令牌泄漏风险:禁用URL传令牌
  5. 加固刷新令牌:对公开客户端施加严格限制
  6. 明晰客户端安全:简化定义以聚焦密钥保护能力

这些变更使OAuth 2.1默认具备远高于OAuth 2.0的安全性,有效应对常见漏洞与攻击向量。新实现应直接采用OAuth 2.1规范。

为什么不开发OAuth 3[编辑 | 编辑源代码]

那么,为什么我要提议OAuth 2.1呢?难道我们不应该摒弃现有的成果,转而创造更简单、更精简的方案吗?

OAuth 3 是一个正在撰写中的规范,由Justin Richer主导,名为“事务授权”(Transactional Authorization,简称TXAuth),并有望最终成为 OAuth 3。该项目采取了一种全新的设计思路,重新思考了如果不受限于 作为原始OAuth 2.0 RFC 6759的扩展 的需求,OAuth及其所有相关规范和扩展(如UMA)可能会呈现怎样的形态。

但众所周知,从零开始创建新规范绝非一蹴而就的过程,更不用说在行业内获得广泛采用了。因此,在OAuth 3的开发过程中——这将耗费数年时间完成——仍有空间在此期间对OAuth 2进行优化完善。------ Aaron Parecki , 2019年12月12日

举例讲解[编辑 | 编辑源代码]

我们用一个大家熟悉的场景—— “游乐园” 来形象地理解 OAuth 2.0/2.1 中授权服务器 (AS)、身份提供者 (IdP)、客户端 (Client) 和资源服务器 (Resource Server) 的关系和协作:

场景设定:

  1. 你 (用户/资源拥有者): 想去一个大型游乐园(比如叫“欢乐世界”)玩。
  2. 第三方 App (客户端): 一个叫“畅游助手”的手机App。它承诺可以帮你预订“欢乐世界”里的热门项目(比如过山车、摩天轮)、查看实时排队时间、甚至购买快速通行证。但它本身不是“欢乐世界”官方的东西。
  3. 欢乐世界售票处 & 身份管理处 (授权服务器 AS + 身份提供者 IdP):
    • 售票处窗口 (授权服务器 AS 的主要功能):
      • 负责售票(发放令牌):发放允许你玩项目的“游玩门票”(访问令牌 Access Token)和“续票凭证”(刷新令牌 Refresh Token)。
      • 检查App资质(客户端认证):确认“畅游助手”这个App是经过他们审核、允许接入的合法合作伙伴(有合法的Client ID和Secret)。
      • 征得你的同意(用户授权):当你第一次通过App连接时,会弹出一个窗口问你:“’畅游助手’App想获取你的基本资料(姓名、头像)并帮你预订项目,你同意吗?” 这个窗口本质上是售票处在征询你的意见
    • 入园闸机 & 身份信息库 (身份提供者 IdP 的主要功能):
      • 验票入园(用户认证):你入园时,闸机(或工作人员)要验证你是你!这通常是通过扫描你的官方电子门票、年卡或者刷脸/指纹(对应用户名密码/MFA)来完成。这一步确认了“你是谁”。
      • 管理你的身份档案(身份信息管理):“欢乐世界”内部有一个数据库,记录着所有注册会员的真实身份信息(姓名、照片、会员号、购买记录等)。这就是你的核心身份档案
    • 重要提示: 在“欢乐世界”这个例子里,“售票处”和“入园闸机/身份信息库”虽然物理位置可能不同,但都属于“欢乐世界”官方运营体系,紧密集成。这对应现实中AS和IdP通常是同一个服务或深度集成。
  4. 欢乐世界里的游乐项目 (资源服务器 Resource Server): 比如过山车“极速飞龙”、摩天轮“星空之眼”。它们只认“欢乐世界”官方发放的、有效的“游玩门票”(访问令牌)。它们不关心你是通过什么App买的票,只关心票是不是真的、有没有权限玩本项目(比如你的票是否包含该项目或者有快速通行证)。

整个流程(对应授权码流程):

  1. 你想用“畅游助手”App订“极速飞龙” (用户发起请求): 你打开“畅游助手”App,点击“预订极速飞龙”。
  2. App把你带到“欢乐世界”售票处 (重定向到授权端点): App弹出一个窗口(或者跳转到浏览器),把你带到“欢乐世界”官方售票处的特定窗口(AS的/authorize端点)。App告诉售票员:“这是我的证件(Client ID),我想帮这位游客(指你)订‘极速飞龙’,订成功后请把凭证发回给我的办公室(redirect_uri)。”
  3. 售票处检查App并让你验明正身 (AS处理请求,触发IdP认证):
    • 售票员先检查“畅游助手”的证件(Client ID)是否有效、登记在册(客户端认证)。
    • 然后售票员对你说:“要帮你订票,我需要先确认你是我们‘欢乐世界’的合法游客。请去那边的闸机刷一下你的年卡/门票验明身份!” (AS要求用户认证)
  4. 你到闸机验票/刷脸 (用户认证 - IdP工作): 你走到入园闸机(IdP),刷了你的年卡或者进行了人脸识别。闸机系统(IdP)验证通过,确认了“你是你” (用户认证成功),并将这个成功信息(“用户123456已验证通过”)通知回售票处 (AS)
  5. 售票处征询你的同意 (用户授权 - AS工作): 你回到售票窗口。售票员(AS)现在知道你是谁了,然后问你:“‘畅游助手’App想帮你预订‘极速飞龙’,并且需要知道你的名字和头像来显示预订信息。你同意吗?” (用户授权界面)。你点击“同意”。
  6. 售票处给App一张“兑换券” (颁发授权码): 售票员(AS)没有直接给你票,而是写了一张“兑换券”(授权码 Authorization Code),并告诉App:“拿着这张兑换券,带上你的正式证件(Client Secret),去我们后台的‘令牌办公室’(/token 端点)换真正的票吧。” 同时把你(用户的浏览器)送回了“畅游助手”App。
  7. App后台兑换“真门票” (交换令牌 - 客户端到令牌端点): “畅游助手”App的后台服务器,拿着“兑换券”(授权码)和自己的正式证件(Client ID + Client Secret),悄悄跑到“欢乐世界”后台的“令牌办公室”(AS的 /token 端点)。
  8. 令牌办公室核发“游玩门票”和“身份卡” (颁发令牌 - AS工作):
    • 令牌办公室(AS)工作人员:
      • 仔细检查“兑换券”(授权码)真假。
      • 核对“畅游助手”的证件(Client ID/Secret)并确认无误。
      • 向身份管理处(IdP)查询: “用户123456同意给‘畅游助手’哪些权限?他的公开信息(比如名字、头像)可以给吗?” (AS 基于IdP的身份信息生成ID Token和UserInfo)
    • 确认无误后,工作人员制作并发放:
      • “游玩门票” (访问令牌 Access Token): 这张票上印着“允许用户123456通过‘畅游助手’App预订和乘坐‘极速飞龙’一次”(包含权限范围 scope)。
      • 可选 “续票凭证” (刷新令牌 Refresh Token): 如果“游玩门票”过期了(比如当天有效),App可以凭这个凭证再来换新票,不用你再跑一趟售票处重新认证授权。
      • “身份卡” (ID Token - 来自IdP): 一张小卡片,上面写着官方认证的信息:“持票人:用户123456(你的唯一标识),由欢乐世界于X时X分签发”。这证明了你成功认证过身份
    • 把这些票和卡都给了“畅游助手”App的后台。
  9. App用“游玩门票”帮你订项目 (访问资源): “畅游助手”App拿到“游玩门票”(Access Token),带着它去“极速飞龙”项目的后台系统(资源服务器RS),说:“这是用户123456的票,帮他预订下午3点场次。” App在请求中出示这张“门票”。
  10. “极速飞龙”项目组验票 (资源服务器验证令牌): “极速飞龙”项目组(资源服务器)的工作人员:
    • 拿出一个“欢乐世界”官方发的验票机(对应RS配置的令牌验证密钥或自省端点)。
    • 扫描“游玩门票”(验证Access Token的签名、有效期)。
    • 查看票面信息:确实是官方发的真票!有效期没过!并且票上明确写着允许预订“极速飞龙”(检查scope)。
    • 于是,项目组确认预订成功,并把信息返回给App。App再告诉你预订成功!
  11. 后续可能:
    • 如果“游玩门票”过期了(比如一天有效),App可以用“续票凭证”(Refresh Token)再去“令牌办公室”(/token端点)换一张新的“游玩门票”(新的Access Token),无需你再次去闸机验票和售票处同意
    • 如果App想显示你的名字和头像,它可以用“游玩门票”(Access Token)去“欢乐世界”的“游客信息服务中心”(/userinfo端点,由IdP提供或AS代理)查询,服务中心确认票有效后,返回你的公开信息(姓名、头像)。

功能切分总结 (回到关键点):

  • 身份提供者 (IdP) - “入园闸机 & 身份信息库”:
    • 核心工作: 证明“你是谁” (用户认证)管理你的核心身份档案
    • 在流程中:负责第4步的“验票入园/刷脸”。
    • 提供生成ID Token所需的身份断言。
    • 提供/userinfo端点查询用户信息。
  • 授权服务器 (AS) - “售票处 & 令牌办公室”:
    • 核心工作: 管理“谁(客户端)能代表你做什么”(授权)发放“通行证”(令牌)
    • 在流程中:负责检查App资质(第3步)、征得你的同意(第5步)、发放“兑换券”(第6步)、验证“兑换券”和App凭证(第8步)、制作并发放“游玩门票”(Access Token)、“续票凭证”(Refresh Token)、“身份卡”(ID Token) (第8步)。
    • 定义令牌规则,提供验证令牌的方法(如JWKS端点)。
  • 协作关键点:
    • AS 依赖 IdP 来确认用户身份(第4步)。
    • AS 在征得用户同意(第5步)和确认客户端合法后,综合IdP的身份断言和用户的授权决策,颁发代表授权的Access Token 和 代表认证的ID Token。
    • 资源服务器(游乐项目)只认AS发的票(Access Token),不直接和IdP打交道

一句话比喻:

IdP (闸机/档案库) 是确认“你是你”的保安。AS (售票处/令牌办) 是根据保安确认结果和你本人的同意,给第三方App开“游玩许可”的票务中心。游乐项目只认票务中心开的真票。

小记[编辑 | 编辑源代码]

  1. 资源所有者 (Resource Owner) - 核心实体!
    • 角色: 这是 拥有被保护资源并能够授权访问这些资源的主体。在绝大多数情况下,资源所有者就是 最终用户 (End-User)。例如:
      • 您(用户)是您在社交媒体上的照片(资源)的所有者。
      • 您(用户)是您邮箱里的邮件(资源)的所有者。
    • 关键职责:
      • 认证: 向 IdP (或集成 IdP 功能的 AS) 证明自己的身份。
      • 授权: 在 AS 提供的同意界面上,决定是否授予客户端所请求的权限(Scope)。
    • 为什么重要? OAuth 的核心思想就是 代表资源所有者进行授权。资源所有者是整个流程的起点和授权决策的最终来源。没有资源所有者,就没有委托授权。
    • 在之前的例子中: “你” 就是资源所有者(拥有游玩权限和个人信息)。你进行“入园验证”(认证)和在“售票处同意”(授权)的行为,就是资源所有者在履行其角色。
    • 注意: 虽然最常见的是自然人用户,但资源所有者理论上也可以是 一个组织或一个自动化系统(例如,在机器对机器/M2M场景中,使用客户端凭证流程时)。
  2. 用户代理 (User Agent) - 关键组件但不是独立“实体”
    • 角色: 资源所有者用来与客户端和授权服务器交互的 软件。最常见的用户代理就是 Web 浏览器(Chrome, Firefox, Safari等),也可以是移动应用内的 WebView 组件。
    • 功能: 它负责:
      • 在授权码流程中,将用户重定向到 AS 的授权端点。
      • 呈现 AS 的登录页面和同意界面给用户。
      • 将授权码带回到客户端指定的重定向 URI。
    • 重要性: 它是资源所有者参与授权流程的关键载体。OAuth 设计(尤其是授权码流程)很大程度上依赖于用户代理的安全特性(如同源策略)来保护凭证(特别是授权码)。
    • 为什么不算独立“实体”? 在协议规范中,用户代理被视为资源所有者使用的工具,而不是一个具有独立协议角色的实体(如AS、Client、RS那样)。它更像一个通信通道。
  3. 令牌 (Tokens) - 核心对象但不是“实体”
    • 它们是流程中传递的关键凭证:
      • 访问令牌 (Access Token): 客户端用来访问资源服务器的令牌。代表资源所有者的授权。
      • 刷新令牌 (Refresh Token): (可选) 客户端用来向 AS 获取新的访问令牌(当旧的过期时)。
      • 授权码 (Authorization Code): (在授权码流程中) 一个短期有效的代码,客户端用它向 AS 交换令牌。设计上是为了避免敏感凭据通过用户代理传递。
      • ID令牌 (ID Token): (在 OIDC 中) 一个 JWT,包含关于用户身份认证的信息(由 AS/OP 签发)。
    • 重要性: 它们是协议安全性和功能实现的基石。
    • 为什么不算“实体”? 它们是 被操作的对象凭证,而不是参与交互的角色或系统。
  4. 授权管理员 (Authorization Administrator) - 部署/管理角色
    • 角色: 负责在 AS 上 注册和管理客户端应用 的人员或系统。例如,当“畅游助手”App 想要接入“欢乐世界”的 OAuth 服务时,需要有人代表“欢乐世界”在 AS 上为“畅游助手”创建客户端记录(分配 Client ID/Secret,配置重定向 URI、授权范围等)。
    • 重要性: 确保只有合法的客户端才能参与流程,是安全的第一道防线。
    • 为什么不算协议“实体”? 这是部署和管理层面的角色,不直接参与标准的 OAuth 协议运行时交互。
  5. 策略执行点/策略决策点 (PEP/PDP) - 高级架构概念
    • 在更细粒度的授权架构(如 ABAC)中:
      • 策略执行点 (PEP): 通常集成在资源服务器中。在收到客户端的访问请求(携带Access Token)后,向 策略决策点 (PDP) 发起授权决策请求(“这个Token对这个资源执行这个操作允许吗?”)。
      • 策略决策点 (PDP): 评估策略规则,做出“允许”或“拒绝”的决策,并将结果返回给 PEP。AS 有时会包含一个 PDP 组件,或者 PDP 是一个独立的服务(如 Open Policy Agent)。
    • 与 OAuth 2.1 的关系: OAuth 2.1 主要定义了如何获取访问令牌(代表粗粒度授权 Scope)。访问令牌本身通常包含足够的信息(Scope,可能还有 Claims)让 RS 做出基本的访问控制决策(RS 这时充当了简单的 PEP+PDP)。对于更复杂的授权(基于用户属性、资源属性、环境属性等),往往会将 OAuth 2.1 与更精细的授权系统结合使用。
    • 为什么不算核心 OAuth 2.1 “实体”? 它们是授权模型扩展的一部分,超出了 OAuth 2.1 核心协议规范的范围。

总结[编辑 | 编辑源代码]

  1. 资源所有者 (Resource Owner) - 核心授权来源(通常是人)。
  2. 客户端 (Client) - 想要访问资源的应用。
  3. 授权服务器 (Authorization Server - AS) - 颁发令牌的中心。
  4. 资源服务器 (Resource Server) - 托管受保护资源的服务器,验证令牌。
  5. 身份提供者 (Identity Provider - IdP) - 认证资源所有者身份(在 OIDC 或需要明确身份的场景中与 AS 紧密耦合/集成)。

关键补充说明[编辑 | 编辑源代码]

  • 用户代理 (User Agent) 是资源所有者参与流程的必备工具(主要是浏览器)。
  • 令牌 (Tokens) 是核心交互对象。
  • 授权管理员PEP/PDP 更多是部署、管理和扩展层面的概念。

用银行例子巩固概念[编辑 | 编辑源代码]

  1. 资源所有者 (你): 拥有银行账户里的钱(资源)。
  2. 客户端 (“家庭记账”App): 想帮你分析消费,需要读取你的银行交易记录。
  3. 授权服务器 (AS - 银行的授权中心): 银行的 OAuth 服务。提供登录界面(可能集成IdP)和授权同意界面(“家庭记账App想访问你最近6个月的交易,同意吗?”),颁发访问令牌。
  4. 身份提供者 (IdP - 银行的登录系统): 验证你的网银用户名密码/指纹(认证你是账户主人)。通常和 AS 是同一套系统。
  5. 资源服务器 (RS - 银行的交易记录API服务器): 存储并提供你的交易数据。它只认银行 AS 签发的有效访问令牌。
  6. 用户代理: 你手机上的浏览器或银行App内的浏览器组件,用来完成登录和授权。
  7. 授权管理员: 银行负责审核“家庭记账”App资质并在银行AS上为其注册开通接口权限的工作人员。
寻星知识库使用 Cookie 技术提升您的浏览体验,这需要在您的浏览器存储部分信息。禁用 Cookie 将导致部分功能无法正常使用。 寻星团队将严格遵守隐私政策,并尽可能保护您的信息安全。 继续浏览寻星知识库,视为您同意启用 Cookie 并生成、存储相关数据。