【问题标题】:What is the OAuth 2.0 Bearer Token exactly?OAuth 2.0 Bearer Token 到底是什么?
【发布时间】:2014-11-08 09:32:21
【问题描述】:

根据RFC6750-The OAuth 2.0 Authorization Framework: Bearer Token Usage,承载令牌为:

一种安全令牌,具有任何拥有该令牌的一方(“持有者”)可以以任何其他拥有它的一方可以使用的任何方式使用令牌的属性。

对我来说,这个定义很模糊,我找不到任何规范。

  • 假设我正在实现一个授权提供程序,我可以为不记名令牌提供任何类型的字符串吗?
  • 可以是随机字符串吗?
  • 是否必须是某些属性的 base64 编码?
    应该散列吗?
  • 服务提供者是否需要查询授权提供者才能验证此令牌?

感谢您的任何指点。

【问题讨论】:

  • 假设我正在实现一个授权提供程序,我可以为不记名令牌提供任何类型的字符串吗?它可以是随机字符串吗?访问令牌通过 Auth0 的 OAuth 2.0 端点发布:/authorize 和 /oauth/token。您可以使用任何与 OAuth 2.0 兼容的库来获取访问令牌。如果您还没有首选的 OAuth 2.0 库,Auth0 提供了适用于多种语言和框架的库。

标签: oauth bearer-token


【解决方案1】:

不记名令牌
任何一方拥有的财产的安全令牌 令牌(“持有者”)可以以任何其他方式使用令牌 拥有它的一方可以。使用不记名令牌不会 要求持有人证明拥有加密密钥材料 (所有权证明)。

承载令牌由身份验证服务器为您创建。当用户对您的应用程序(客户端)进行身份验证时,身份验证服务器就会为您生成一个令牌。不记名令牌是用于 OAuth 2.0 的主要访问令牌类型。 Bearer 令牌基本上表示“授予此令牌的持有者访问权限”。

承载令牌通常是由身份验证服务器创建的某种不透明值。这不是随机的;它是根据授予您访问权限的用户和您的应用程序获得访问权限的客户端创建的。

例如,为了访问 API,您需要使用访问令牌。访问令牌是短暂的(大约一个小时)。您使用不记名令牌来获取新的访问令牌。要获取访问令牌,您需要将此不记名令牌连同您的客户端 ID 发送给身份验证服务器。这样,服务器就知道使用不记名令牌的应用程序与创建不记名令牌的应用程序相同。示例:我不能只获取为您的应用程序创建的不记名令牌并将其与我的应用程序一起使用,因为它不是为我生成的,所以它不起作用。

Google 刷新令牌如下所示:1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM

从评论中复制:我认为您提供的不记名令牌没有任何限制。我能想到的唯一一件事是,允许不止一个是很好的。例如,用户最多可以对应用程序进行 30 次身份验证,而旧的不记名令牌仍然可以使用。哦,如果有一个 6 个月没有使用,我会从你的系统中删除它。必须由您的身份验证服务器生成并验证它们,因此如何格式化由您决定。

更新:

在每个 Inline Action HTTP 请求的 Authorization 标头中都设置了 Bearer Token。例如:

POST /rsvp?eventId=123 HTTP/1.1
Host: events-organizer.com
Authorization: Bearer AbCdEf123456
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/1.0 (KHTML, like Gecko; Gmail Actions)

rsvpStatus=YES

上例中的字符串"AbCdEf123456" 是不记名授权令牌。这是身份验证服务器生成的加密令牌。与操作一起发送的所有不记名令牌都有问题字段,观众字段将发送者域指定为 https:// 形式的 URL。例如,如果电子邮件来自 noreply@example.com,则受众为 https://example.com

如果使用不记名令牌,请验证请求来自身份验证服务器并且是针对发送方域的。如果令牌未验证,则服务应使用 HTTP 响应代码 401(未授权)响应请求。

不记名令牌是 OAuth V2 标准的一部分,被许多 API 广泛采用。

【讨论】:

  • 承载令牌并不意味着它是一个刷新令牌@AqeelSmith tools.ietf.org/html/rfc6750#section-6.1.1
  • 第一段暗示承载令牌是刷新令牌而不是访问令牌。不是这种情况。来自承载令牌规范“该规范描述了当 OAuth 访问令牌是承载令牌时如何发出受保护的资源请求。” RFC6750
  • 看了答案,我还以为Bearer token和refresh tokens是一样的。应该更新答案以澄清这一点。
  • 这个答案非常具有误导性。承载令牌不是刷新令牌,正如该答案的初始声明所述。请更正。
  • @think01 完成。五年后你对某事的理解有多大的不同。
【解决方案2】:

在阅读您的问题时,我尝试在 Internet 上搜索不记名令牌是如何加密或签名的,但没有成功。我猜不记名令牌没有经过哈希处理(可能是部分,但不是全部),因为在这种情况下,将无法解密它并从中检索用户属性。

但您的问题似乎是试图找到有关 Bearer 令牌功能的答案:

假设我正在实施一个授权提供程序,我可以提供任何 不记名令牌的字符串类型?可以是随机字符串吗?做 它必须是某些属性的base64编码吗?应该是 散列?

所以,我将尝试解释 Bearer 令牌和 Refresh 令牌的工作原理:

当用户通过 SSL 向服务器请求令牌发送用户和密码时,服务器返回两件事:访问令牌刷新令牌

访问令牌是一个不记名令牌,您必须将其添加到所有请求标头中才能作为具体用户进行身份验证。

Authorization: Bearer <access_token>

访问令牌是一个加密字符串,其中包含您希望的所有用户属性、声明和角色。 (如果您添加更多角色或声明,您可以检查令牌的大小是否增加)。 一旦资源服务器接收到访问令牌,它将能够解密它并读取这些用户属性。这样,用户将与所有应用程序一起被验证和授予。

访问令牌的有效期很短(即 30 分钟)。 如果访问令牌的有效期很长,那将是一个问题,因为理论上不可能撤销它。所以想象一个角色=“Admin”的用户更改为“用户”。如果用户使用 role="Admin" 保留旧令牌,他将能够使用管理员权限访问令牌,直到令牌到期。 这就是为什么访问令牌的有效期很短。

但是,我想到了一个问题。如果访问令牌的有效期很短,我们必须每隔很短的时间发送用户和密码。这安全吗?不,不是。我们应该避免它。那时刷新令牌似乎解决了这个问题。

刷新令牌存储在数据库中,有效期较长(例如:1 个月)。

用户可以使用用户在第一次令牌请求中收到的刷新令牌获取新的访问令牌(例如,当它过期时,每 30 分钟一次)。 当访问令牌过期时,客户端必须发送一个刷新令牌。如果数据库中存在此刷新令牌,则服务器将向客户端返回一个新的访问令牌和另一个刷新令牌(并将旧的刷新令牌替换为新令牌)。

如果用户访问令牌已被泄露,则必须从数据库中删除该用户的刷新令牌。这样,令牌将仅在访问令牌过期之前有效,因为当黑客尝试获取发送刷新令牌的新访问令牌时,此操作将被拒绝。

【讨论】:

  • 我不明白这部分:“一旦授权服务器收到访问令牌,它将能够解密并读取这些用户属性。这样,用户将被验证并被授予所有应用程序”。授权服务器不是授予访问令牌而不是接收它的服务器吗?我正在努力解决这个问题,并且很多示例清楚地区分了授权服务器和资源服务器。我的理解是您从授权服务器获取访问令牌,然后将其与您向资源服务器发出的每个请求一起传递?
  • @kivikall 你是对的。我已经在答案中更改了它。资源服务器在每个请求中接收令牌(授权服务器在令牌创建过程中加密的令牌)并对其进行解密。
  • @kivikall 实际上,解密令牌应该是与授权有关的东西,因此它应该属于授权服务器。这就是为什么 a 在答案中写了它。但在实践中,这意味着在每个请求中,您必须使用授权服务器验证收到的令牌(可能执行另一个请求)。因此,为了避免性能损失,最好将一些解密令牌的功能提供给资源服务器。查看下一个链接:stackoverflow.com/questions/12296017/…
  • 但是对于每个请求,资源服务器都应该检查提供的 AccessToken 是否对授权服务器有效。因此,如果角色更改,身份验证服务器可以立即反映更改,对吗?另外,如果 AccessToken 被泄露,我们为什么要删除 RefreshToken? RefreshToken 不能根据 AccessToken 计算出来,所以当它过期时,黑客会再次被阻止。
  • “访问令牌是加密字符串”。加密还是编码?
【解决方案3】:

不记名标记是字母、数字、“-”、“.”的一个或多个重复。 , "_" , "~" , "+" , "/" 后跟 0 个或多个 "="。

RFC 6750 2.1. Authorization Request Header Field(格式为 ABNF(增强型 BNF))

The syntax for Bearer credentials is as follows:

     b64token    = 1*( ALPHA / DIGIT /
                       "-" / "." / "_" / "~" / "+" / "/" ) *"="
     credentials = "Bearer" 1*SP b64token

它看起来像 Base64,但根据Should the token in the header be base64 encoded?,它不是。

深入研究“HTTP/1.1,第 7 部分:身份验证”**, 但是,我看到 b64token 只是一个 ABNF 语法定义 允许通常在 base64、base64url 等中使用的字符。所以 b64token 没有定义任何编码或解码,而只是 定义授权部分可以使用哪些字符 将包含访问令牌的标头。

这完全解决了 OP 问题列表中的前 3 个项目。所以我扩展了这个答案来解决第 4 个问题,关于是否必须验证令牌,所以@mon 可以随意删除或编辑:

授权者负责接受或拒绝http请求。如果授权人说令牌有效,则由您决定这意味着什么:

  • 授权方是否有办法检查 URL、识别操作并查找一些基于角色的访问控制数据库以查看是否允许?如果是并且请求通过,则服务可以假定它是允许的,并且不需要验证。
  • 令牌是全有还是全无,所以如果令牌正确,则允许所有操作?那么服务就不需要验证了。
  • token 是否表示“允许此请求,但这里是角色的 UUID,您检查是否允许操作”。然后由服务来查找该角色,并查看该操作是否被允许。

参考文献

【讨论】:

  • 您根本没有解释 Bearer 令牌的用途。
  • 这是最好的,也是迄今为止最清晰的答案。如果您查看 OP 问题,它至少回答了 4 个要点中的 3 个,如果不是全部 4 个。OP 问题不是关于目的,而是关于令牌的内容和(列表中的第 4 项)是否需要待验证。
  • @JaimeHablutzel,请阅读问题(原始问题中的 4 个要点)。四个中的哪一个要求“不记名令牌的目的”?我提供了第 1 到第 3 点的答案。请参阅上面 Oliver 的评论,并请专注于“回答问题”。
  • 1*SP 是指1 space 吗?我花了三十多分钟才解决这个问题
  • @byxor,它来自 RFC。也许这是 IETF 中的一个常见约定。
【解决方案4】:

请先阅读rfc6749 sec 7.1中的示例。

不记名令牌是一种访问令牌,不需要PoP(proof-of-possession)机制。

PoP 意味着一种多因素身份验证,以使访问令牌更安全。 ref

所有权证明是指降低安全令牌被攻击者窃取和使用风险的加密方法。与“不记名令牌”相比,仅仅拥有安全令牌就可以让攻击者使用它,PoP 安全令牌不能那么容易使用 - 攻击者必须同时拥有令牌本身和访问与相关联的某些密钥令牌(这就是为什么它们有时被称为“持有者”(HoK)令牌)。

也许不是这样,但我想说,

  • 访问令牌 = 支付方式
  • 不记名令牌 = 现金
  • 具有 PoP 机制的访问令牌 = 信用卡(将验证签名或密码,有时需要出示您的 ID 以匹配卡上的姓名)

顺便说一句,“OAuth 2.0 Proof-of-Possession (PoP) 安全架构”现在有一个 draft

【讨论】:

    【解决方案5】:

    不记名令牌就像纸币,例如 100 美元钞票。人们可以使用纸币而不会被问到任何/很多问题。

    Bearer Token 具有任何一方参与的属性的安全令牌 拥有令牌(“持有者”)可以以任何方式使用令牌 拥有它的任何其他方都可以。使用不记名令牌不会 要求持有人证明拥有加密密钥材料 (所有权证明)。

    【讨论】:

      【解决方案6】:

      不记名令牌是一个b64token字符串,要求有就可以使用。除此之外,无法保证该字符串在规范中的实际含义。这取决于实施。

      5.2。威胁缓解

      本文档未指定编码或内容 令牌;因此,关于
      保证令牌完整性保护不在此范围内 文档。令牌完整性保护必须足以
      防止令牌被修改。

      https://datatracker.ietf.org/doc/html/rfc6750#section-5.2

      虽然每次发布令牌时可能是随机的,但缺点是服务器端需要跟踪令牌数据(例如过期)。 JSON Web Token (JWT) 通常用作不记名令牌,因为服务器可以根据令牌中的内容做出决策。

      智威汤逊: https://jwt.io/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-12
        • 1970-01-01
        • 2015-06-12
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 2017-03-15
        • 2015-05-19
        相关资源
        最近更新 更多