ChatGPT解决这个技术问题 Extra ChatGPT

OAuth 2.0 Bearer Token 到底是什么?

根据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 提供了适用于多种语言和框架的库。

D
DaImTo

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

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

Bearer Token 通常是认证服务器创建的某种不透明值。这不是随机的;它是根据授予您访问权限的用户和您的应用程序获得访问权限的客户端创建的。

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

Google 刷新令牌看起来像这样:1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM

从评论中复制:我认为您提供的不记名令牌没有任何限制。我能想到的唯一一件事是,允许不止一个是很好的。例如,用户最多可以对应用程序进行 30 次身份验证,而旧的不记名令牌仍然可以使用。哦,如果有一个 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" 是不记名授权令牌。这是身份验证服务器生成的加密令牌。随操作发送的所有不记名令牌都有问题字段,受众字段将发送者域指定为 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 token 是一样的。应该更新答案以澄清这一点。
这个答案非常具有误导性。承载令牌不是刷新令牌,正如该答案的初始声明所述。请纠正。
@think01 完成。五年对你对某事的理解有多大的不同。
C
Chris Sharp

在阅读您的问题时,我尝试在 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 计算出来,所以当它过期时,黑客会再次被阻止。
“访问令牌是加密字符串”。加密还是编码?
C
Community

不记名令牌是字母、数字、“-”、“.”的一个或多个重复。 , "_" , "~" , "+" , "/" 后跟 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 个项目。所以我扩展了这个答案来解决第四个问题,关于是否必须验证令牌,所以@mon 可以随意删除或编辑:

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

授权者是否有办法检查 URL、识别操作并查找一些基于角色的访问控制数据库以查看是否允许?如果是并且请求通过,则服务可以假定它是允许的,并且不需要验证。

令牌是全有还是全无,所以如果令牌正确,则允许所有操作?然后服务不需要验证。

令牌是否表示“允许此请求,但这里是角色的 UUID,您检查是否允许操作”。然后由服务来查找该角色,并查看该操作是否被允许。

参考

RFC 5234 3.6。可变重复:*规则

RFC 2616 2.1 增强型 BNF


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

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

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

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

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

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

访问令牌 = 付款方式

不记名代币 = 现金

具有 PoP 机制的 access token = 信用卡(签名或密码将被验证,有时需要出示您的 ID 以匹配卡上的姓名)

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


e
ekhanad

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

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


W
Wrexbe

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

5.2.威胁缓解 本文档未指定令牌的编码或内容;因此,关于保证令牌完整性保护的方法的详细建议超出了本文档的范围。令牌完整性保护必须足以防止令牌被修改。

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

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

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