OAuth 2.0 Bearer Token 是什么?

257
根据RFC6750-OAuth 2.0授权框架:使用持有人令牌,持有人令牌是指具有以下属性的安全令牌:任何持有该令牌的一方(“持有人”)都可以像其他持有该令牌的一方一样以任何方式使用该令牌。
对我来说,此定义含糊不清,我找不到任何规范。 - 假设我正在实现授权提供程序,我可以为持有人令牌提供任何类型的字符串吗? - 它可以是随机字符串吗? - 必须是某些属性的base64编码吗? 应该散列吗? - 服务提供商是否需要查询授权提供程序才能验证此令牌?

假设我正在实现一个授权提供程序,我可以为承载令牌提供任何类型的字符串吗?它可以是随机字符串吗?访问令牌通过Auth0的OAuth 2.0端点/authorize和/oauth/token发行。您可以使用任何OAuth 2.0兼容库来获取访问令牌。如果您还没有首选的OAuth 2.0库,Auth0提供了许多语言和框架的库。 - Bharathkumar V
6个回答

214

Bearer Token
拥有此令牌(“持有者”)的任何一方都可以以任何其他拥有者能够使用的方式使用该令牌。使用Bearer Token不需要持有者证明密钥材料的所有权(即proof-of-possession)。

认证服务器会为您创建Bearer Token。当用户验证应用程序(客户端)时,认证服务器会生成一个Token给您。Bearer Token是OAuth 2.0中最常用的访问令牌类型。Bearer token基本上是说“给予此令牌的持有者访问权限”。

Bearer Token通常是认证服务器创建的某种不透明值。它并不是随机的; 它是基于允许您访问的用户和您的应用程序获得访问而创建的。

为了访问API,您需要使用Access Token。Access Token的寿命较短(大约为一小时)。您使用Bearer Token来获取新的Access Token。要获取Access Token,您需要将此Bearer Token与您的客户端ID一起发送到认证服务器。这样,服务器就知道使用Bearer Token的应用程序与创建Bearer Token的应用程序相同。例如:我不能只是拿您的应用程序创建的Bearer Token并将其与我的应用程序一起使用,因为它不是为我生成的。

Google Refresh token 看起来像这样:1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM

从评论中复制:我认为没有任何限制您提供的Bearer Tokens。我所能想到的唯一一件事情就是允许使用多个Bearer Token。例如,用户可以对应用程序进行最多30次身份验证,旧的Bearer Token仍将起作用。但如果有一个Bearer Token在6个月内未被使用,则应将其从系统中删除。它是您的认证服务器将需要生成并验证它们,所以格式由您决定。

更新:

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

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" 是承载授权令牌。这是认证服务器生成的加密令牌。所有随操作发送的承载令牌都具有“issue”字段,其中“Audience”字段指定URL形式为https://的发件人域。例如,如果电子邮件来自noreply@example.com,则受众是https://example.com
如果使用承载令牌,请验证请求是否来自认证服务器并且是用于发件人域的。如果令牌未经验证,则服务应使用HTTP响应代码401(未经授权)响应请求。
承载令牌是OAuth V2标准的一部分,并被许多API广泛采用。

25
“Bearer token doesn't mean its a refresh token” 的意思是“令牌(token)是Bearer类型并不意味着它是一个刷新(refresh)令牌”。该语句的出处为@AqeelSmith的推文,并参考了RFC6750的第6.1.1节。 - Suman Kundu
21
第一段意味着Bearer令牌是刷新令牌而不是访问令牌,但事实并非如此。从Bearer令牌规范来看,“本规范描述了在OAuth访问令牌为Bearer令牌时如何进行受保护资源请求。” RFC6750 - Daniel
13
阅读了这个答案后,我也认为Bearer token和refresh token是相同的。应该更新答案来澄清这一点。 - KurioZ7
8
这个答案非常误导人。如该答案最初所述,Bearer tokens并不是Refresh Token。请进行更正。 - think01
5
@think01 完成了。五年对你对某件事的理解产生了巨大的差异。 - Linda Lawton - DaImTo
显示剩余15条评论

96
阅读您的问题后,我尝试在互联网上搜索Bearer令牌如何加密或签名,但没有成功。我猜测Bearer令牌并没有被哈希(可能部分被哈希,但不完全),因为如果是这样,就无法解密它并从中检索用户属性。
但是您的问题似乎是在尝试寻找有关Bearer令牌功能的答案:
假设我正在实现授权提供程序,我可以为Bearer令牌提供任何类型的字符串吗?它可以是随机字符串吗?它必须是某些属性的base64编码吗?应该进行哈希处理吗?
因此,我将尝试解释Bearer令牌和刷新令牌的工作原理:
当用户通过SSL发送用户和密码请求服务器令牌时,服务器会返回两个东西:一个访问令牌和一个刷新令牌。
访问令牌是一个Bearer令牌,您需要将其添加到所有请求标头中,以便作为具体用户进行身份验证。
Authorization: Bearer <access_token>

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

访问令牌具有短暂的过期时间(例如30分钟)。如果访问令牌具有长时间的过期时间,那么可能会出现问题,因为理论上没有撤销的可能性。因此,想象一下一个具有角色="管理员"的用户变成了"用户"。如果用户保留具有角色="管理员"的旧令牌,他将能够在令牌到期前以管理员权限访问。这就是访问令牌具有短暂过期时间的原因。

但是,一个问题出现了。如果访问令牌具有短暂的过期时间,我们必须每个短时间段发送一次用户和密码。这是安全的吗?不是的,我们应该避免这种情况。这时刷新令牌就出现了,以解决这个问题。

刷新令牌存储在数据库中,并且具有长时间的过期时间(例如:1个月)。

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

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


3
"我不理解这一部分:“一旦授权服务器接收到访问令牌,它将能够解密并读取这些用户属性。 这样,用户将得到验证,并被授予整个应用程序。” 授权服务器不是授予访问令牌而不是接收它吗?我正在努力理解这个主题,很多例子清楚地区分了授权服务器和资源服务器之间的差异。我的理解是,你从授权服务器获取访问令牌,然后将其与您向资源服务器发出的每个请求一起传递?" - kivikall
1
@kivikall 你是对的。我已经在答案中进行了更改。资源服务器在每个请求中接收令牌(授权服务器在令牌创建过程中加密的令牌),并对其进行解密。 - Xavier Egea
1
@kivikall 实际上,解密令牌应该与授权相关,因此应该属于授权服务器。这就是为什么我在答案中写了它的原因。但在实践中,这意味着您必须在每个请求中使用授权服务器验证接收到的令牌(可能执行另一个请求)。因此,为了避免性能损失,最好将一些解密令牌的功能交给资源服务器。请查看下一个链接:https://dev59.com/U2ct5IYBdhLWcg3wKqa9 - Xavier Egea
1
但是在每个请求中,资源服务器都应该检查提供的AccessToken是否有效,以便与授权服务器进行验证。因此,如果角色发生更改,则可以立即通过Auth服务器反映出来,对吧? 另外,如果AccessToken被攻击者获取,为什么我们要删除RefreshToken?RefreshToken无法根据AccessToken计算,因此当其过期时,黑客将再次被阻止。 - mandarin
1
"Access token是一个加密字符串。" 加密还是编码? - Tarun
显示剩余8条评论

12

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

持有令牌是一种访问令牌,不需要PoP(拥有证明)机制。

PoP是一种多因素认证,可以使访问令牌更安全。ref

拥有证明是指用于减轻安全令牌被盗用并被攻击者使用的风险的加密方法。与"持有者令牌"不同,仅拥有安全令牌允许攻击者使用它,而拥有证明安全令牌则不那么容易使用 - 攻击者必须同时拥有令牌本身和与令牌相关的某个密钥的访问权限(这就是为什么它们有时被称为"持有者密钥"(HoK)令牌)。

也许情况并非如此,但我想说:

  • 访问令牌 = 支付方式
  • 持有人令牌 = 现金
  • 具有PoP机制的访问令牌,例如MAC令牌 = 信用卡(需要验证签名或密码,有时需要出示身份证以核对卡上的姓名)

关于"Bearer"这个术语

"Bearer check(支票)"是指一种未命名或未背书的支票。任何实际持有该支票的人都可以兑现或存款,因为它不需要任何特定的身份验证或授权。而"Name check(命名支票)"也被称为定单支票,是特别开给具体个人或组织的支票。要兑现或存入一个命名支票,收款人必须出示适当的身份证明,并在支票背面签字背书。收款人的背书作为银行处理支票并将资金转移给所命名个人或组织的授权。


12

Bearer token是一个或多个字母、数字、"-"、"."、"_"、"~"、"+"、"/"的重复,后面跟着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,但根据头部的令牌是否应该被Base64编码?,它不是。

然而,深入研究一下“HTTP/1.1,第7部分:身份验证”,我发现b64token只是一个ABNF语法定义,允许使用通常用于base64、base64url等的字符。因此,b64token并没有定义任何编码或解码,而是只定义了可以在Authorization头部中包含访问令牌的那部分中使用哪些字符。

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

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

  • 授权者是否有一种方法检查URL、识别操作并查找某个基于角色的访问控制数据库以查看是否允许?如果是,并且请求通过,则服务可以假定它是允许的,不需要进行验证。
  • 如果令牌是全开放或全关闭的,那么如果令牌正确,则允许所有操作。那么服务就不需要进行验证。
  • 令牌是否意味着“允许此请求,但是这是角色的UUID,您检查该操作是否允许”。然后由服务来查找该角色,并查看该操作是否被允许。

参考文献


3
您并没有解释什么是Bearer Tokens的目的。 - Jaime Hablutzel
2
这是最好的,也是最清晰的答案。如果你看一下 OP 的问题,它至少回答了 3 个问题,如果不是全部 4 个问题。OP 的问题不是关于目的,而是关于令牌的内容以及(列表中的第四项)是否需要验证。 - Oliver
2
@JaimeHablutzel,请阅读问题(原问题中的4个要点)。其中哪一个要求“Bearer令牌的目的”?我已经回答了1到3号要点。请看一下Oliver上面的评论,重点是“回答问题”。 - mon
1*SP 是指 1个空格 吗?我花了30多分钟才明白。 - byxor
@byxor,这是来自RFC的。也许在IETF中这是一个常见的约定。 - mon

7

一个承载令牌就像一张货币票据,例如100美元的钞票。人们可以在不被问任何/许多问题的情况下使用这张货币票据。

承载令牌

一种安全令牌,其特性是凭借该令牌(即“持有者”)的任何一方都可以以其他任何持有者可能采取的方式使用该令牌。使用承载令牌不需要持有者证明拥有加密密钥材料(即无需证明持有)。


2
持有者令牌是一个b64token字符串,如果您拥有它,就可以使用它。规范并不保证该字符串的含义,除此之外,实现方式由各自决定。
引用: 5.2. 威胁缓解 本文档未指定令牌的编码或内容;因此,在保证令牌完整性保护的手段方面提出详细建议超出了本文档的范围。令牌完整性保护必须足以防止令牌被修改。

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

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

JWT: https://jwt.io/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接