为了账号安全,请及时绑定邮箱和手机立即绑定

OAuth 2.0与JWT:身份验证与授权的那些事儿(上)

标签:
架构 安全 API

我们先来看看材料中的常用术语。

JWT(JSON Web Token) 是 RFC 7519 中描述的一种开放标准。它定义了一种以 JSON 对象形式传输信息的紧凑方式。服务器使用密钥签署令牌,然后发送给客户端。客户端可以验证此令牌的真伪,使用它来确认身份,从中抽取负载等信息。当我们讨论客户端和服务器之间的交互时,通常会区分访问和刷新令牌。

访问令牌(access token)是访问受保护资源的密钥,通常只在短时间内有效。刷新令牌让你可以请求新的访问令牌,而其生存时间较长。

JWT令牌的一大优点是,它可以使用公钥在客户端进行验证,而无需将它传递给发行它的服务器,并且无需在客户端应用程序侧存储有关活跃会话的信息。此外,该令牌本身很小,可以在POST请求的正文和头信息中传递,同时也可以通过URI查询参数传递。虽然后者安全性较低,但允许实现额外的流程授权机制。

OAuth 2.0 正如标准所描述的,是一种授权框架/协议,描述了如何实现服务间的交互,以便安全地为第三方应用提供授权并限制其访问资源。现在我们来看看 OAuth 2.0 中定义的角色:

  • 资源所有者 — 能为受保护资源提供访问权限的实体,这可以是最终用户或一个系统。在本材料中,资源所有者总是指实际用户。
  • 资源服务器 — 具有受保护资源的服务器,可以通过访问令牌访问该资源。
  • 客户端 — 代表资源所有者并经其同意请求访问受保护资源的应用程序。客户端有两种类型:完整的后端服务(Confidential)和客户端应用程序(Public)。关于每种类型、功能及数据存储能力的详细信息,请参阅 RFC-6749。

简单来说:

  • Web应用客户端 是一种保密客户端。例如,通过用户代理(如web浏览器)与资源所有者交互的后端web应用;
  • 基于用户代理的应用 是一个公共客户端,所有代码都是在用户代理上运行。SPA就是一个很好的例子;
  • 原生应用 也是一种公共客户端。安装在用户设备上的原生应用,比如你手机上安装的任何原生应用。

在进一步探讨单点登录(SSO)以及网页应用和原生应用之间的端到端会话实现时,我们将立即明确这两种用户代理之间的不同:

  • 一个外部用户代理(UA) 可以处理用户的授权请求。它是在目标原生应用内部的一个受保护的独立实体。应用程序无权访问该UA的会话存储或通过该UA显示的页面内容。简单来说,这就像操作系统的内置浏览器。
  • 嵌入式用户代理(UA) 是内置在原生应用中的。应用程序可以完全访问会话存储和页面内容。一个典型的例子就是原生应用中常用的WebView。
OAuth 2.0:基础流程

让我们回到OAuth 2.0。在RFC-6749中,详细描述了四种流程。我们快速回顾一下下面的内容。

  • 授权码—— 此流程基于重定向(redirect)。客户端必须能够与用户代理(通常是浏览器)进行交互,并提供客户端与服务器的交互。因此,此流程仅适用于保密客户端。我们将在后面详细讨论它。
  • 客户端凭证 —此流程仅适用于机器对机器(M2M)应用(例如代理服务器、CLI和后端服务)。它类似于“常规”的授权,基于客户端ID和客户端密钥进行。实际上,这相当于用户的登录名和密码。客户端向授权服务器发送客户端ID和客户端密钥的请求,并作为响应收到访问令牌以访问请求的资源。
  • 隐式 —此流程为可以工作重定向URI(例如SPA或移动应用)的公共客户端“适应”授权码流程。主要区别在于,授权服务器在成功授权资源所有者后返回访问令牌,而不是接收授权码并使用重定向URI中的查询交换访问令牌。现在,标准的主要建议是使用带有PKCE的授权码流程。它更安全:它不会以明文形式传输令牌,并允许客户端返回并使用刷新令牌。
  • 资源所有者密码凭证。 此流程被认为已过时,不建议使用,因为它存在安全风险。资源所有者必须通过位于客户端上的表单传输登录名和密码,这最初使它只能用于完全值得信赖的客户端。
  • 设备授权是一个额外的第五流程。 虽然我之前提到OAuth 2.0只有四个流程,但此流程在2019年通过RFC 8628被添加。它描述了为难以输入登录名和密码的设备设计的流程(例如电视机/机顶盒/没有图形界面的设备)。设备向资源所有者(即设备所有者)显示用户代码和验证URI/QR码,并开始向授权服务器查询完成确认。资源所有者从另一个设备访问链接并确认发放所需的权限。

值得注意的是,早在2012年OAuth 2.0(RFC 6749)就已经发布,而更新版本的OAuth 2.1标准的工作已经进行了很长时间。新版本将结合几个已发布的标准:适用于原生应用的OAuth 2.0 (RFC 8252)、用于代码交换的证明密钥(PKCE)、适用于基于浏览器的应用程序的OAuth、OAuth 2.0的安全最佳实践(最佳实践),以及已被弃用的功能。草案的最终日期一再被推迟,目前定于2024年12月5日,但预计还会再次推迟。即将推出的版本的主要变化有:

  • 所有使用授权码流程的客户端现在必须使用PKCE流程
  • 资源所有者密码凭证和隐式授权(response_type=token)不再属于规范
  • 不允许通过查询URI传递令牌
  • 对刷新令牌施加更严格的限制措施
带有代码交换证明密钥的授权码流程是如何运作的?

结合PKCE的授权码流程是基于常规授权码流程,并且几乎是在为公共客户端(例如SPA和原生移动应用)实现授权时的唯一选择。该流程在相应的OAuth 2.0 RFC 7636中有详细的描述。我们将分析授权码流程

此流程通过目标应用程序创建的代码验证器扩展了授权流程。主要的一点是,如果攻击者截获了授权码,则没有相应的代码验证器,就无法换取令牌。

流程算法如下所示:

  1. 当用户需要授权时,例如点击登录按钮。
  2. 目标应用生成一个随机的code_verifier和code_challenge,并将它们保存在应用中(详情请参阅RFC-7636)。
  3. 应用程序将浏览器重定向到授权服务器端点,同时附带上之前生成的code_challenge。
  4. 授权服务器也会记住此会话中的code_challenge。重要的是code_verifier保留在应用内部,不会在网络上传输。
  5. 用户在授权服务器页面上输入登录名和密码,并选择目标应用可以获取的权限。
  6. 授权服务器将用户重定向回客户端,并返回授权码,但不返回code_challenge。
  7. 应用程序使用授权码交换token,过程与授权流中的几乎一致,但会额外传递在步骤2中保存的code_verifier。
  8. 授权服务器根据token请求的负载数据计算code_challenge,并将其与在步骤3中发送的code_challenge进行比较。如果这两个值匹配,则返回一组用于访问受保护资源的token。
授权 vs 鉴权

了解了OAuth 2.0的工作原理后,回到基础知识,深入理解认证和授权及其区别要比讨论OpenID和单点登录(SSO)容易得多。虽然这些概念看似直观,但这些术语常常引起很多困惑,并且处于一个“灰色地带”。

授权是指一个应用向另一个应用授予访问数据和功能的权限。所以,本质上,它是在代表用户将执行某些操作的权利授予外部应用,而不需要知道用户的具体身份。我喜欢 Aaron Parecki 在他关于 OAuth 2.0 规范的文章中提到的例子,具体例子中酒店使用门禁卡。

想象你终于到达了期待已久的度假地,入住酒店后,收到了一张房间卡。凭这张卡,你可以在度假期间使用酒店的各项服务和你的房间。卡片上没有任何个人信息,如登记详情和护照信息,只涉及逗留期间特定服务的使用。从这个角度来看,这张卡片就像OAuth 2.0中的访问令牌一样。

OAuth 2.0 只表明用户已授权该应用程序代表他们操作,而无需用户自己识别,总之,这并不提供一种机制来查明用户是通过何种方式被认证的。

认证就是确认某个用户的真实身份,也就是说,确认某个用户确实是其声称的身份。这就是OpenID Connect的目的。

我会在下一部分继续讲OpenID Connect以及其他。敬请关注。

嘿,各位专业大佬,咱们在LinkedIn上加个好友吧!!👋

点击这里查看 https://www.linkedin.com/in/dmytronasyrov

如果觉得自在,你们可以在Pharos Production留言说“嗨”!我们让软件活起来! 👋✨

请访问 https://pharosproduction.com 以获取更多信息。

加入我们激动人心的旅程,一起来体验吧!🌍✨,这就是Ludo — Web3 世界的声誉系统

https://ludo.com (这是一个游戏网站)

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消