根据RFC6750-The OAuth 2.0授权框架:持名令牌使用,持名令牌为:

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

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

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


当前回答

当我读到你的问题时,我试图在互联网上搜索不记名令牌是如何加密或签名的,但没有成功。我猜不记名令牌没有散列(可能是部分散列,但不是完全散列),因为在这种情况下,将不可能解密它并从中检索用户属性。

但你的问题似乎是试图找到关于持名代币功能的答案:

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

因此,我将尝试解释持有者令牌和刷新令牌是如何工作的:

当用户向服务器请求通过SSL发送用户和密码的令牌时,服务器返回两个东西:Access令牌和Refresh令牌。

访问令牌是一种记名令牌,您必须在所有请求头中添加该令牌,以便作为具体用户进行身份验证。

Authorization: Bearer <access_token>

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

访问令牌的有效期很短(例如。30分钟)。 如果访问令牌的有效期很长,这将是一个问题,因为理论上不可能撤销它。因此,假设一个role=“Admin”的用户更改为“user”。如果用户保留了role="Admin"的旧令牌,他将能够使用Admin权限访问到令牌到期。 这就是为什么访问令牌的有效期很短。

但是,我想到了一个问题。如果一个访问令牌的有效期很短,我们必须在每个短时间内发送用户和密码。这安全吗?不,它不是。我们应该避免它。这时就出现了Refresh令牌来解决这个问题。

刷新令牌存储在DB中,过期时间很长(例如:1个月)。

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

如果用户访问令牌已被破坏,则必须从DB中删除该用户的刷新令牌。这样,令牌将只在访问令牌过期之前有效,因为当黑客试图获得发送刷新令牌的新访问令牌时,此操作将被拒绝。

其他回答

不记名的令牌 一种具有任何一方拥有的财产的安全令牌 令牌(“持有者”)可以以任何其他方式使用令牌 拥有它的一方可以。使用不记名令牌则不然 要求持有人证明拥有密码匙资料 (所有权证明)。

身份验证服务器为您创建了承载令牌。当用户对应用程序(客户端)进行身份验证时,身份验证服务器就会为您生成一个Token。无记名令牌是OAuth 2.0使用的主要访问令牌类型。一个不记名令牌基本上说的是“给这个令牌的持有者访问权”。

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

In order to access an API for example you need to use an Access Token. Access tokens are short lived (around an hour). You use the bearer token to get a new Access token. To get an access token you send the Authentication server this bearer token along with your client id. This way the server knows that the application using the bearer token is the same application that the bearer token was created for. Example: I can't just take a bearer token created for your application and use it with my application it wont work because it wasn't generated for me.

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

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

更新:

在每个内联动作HTTP请求的授权报头中设置承载令牌。例如:

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字段,受众字段将发送方域指定为https://.形式的URL例如,如果邮件来自noreply@example.com,受众就是https://example.com。

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

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

无记名代币类似于纸币,例如100美元纸币。人们不用问任何问题就可以使用这种纸币。

不记名令牌一种具有任何一方的属性的安全令牌 持有令牌(“持有者”)可以以任何方式使用令牌 任何其他拥有它的人都可以。使用不记名令牌则不然 要求持有人证明拥有密码匙资料 (所有权证明)。

当我读到你的问题时,我试图在互联网上搜索不记名令牌是如何加密或签名的,但没有成功。我猜不记名令牌没有散列(可能是部分散列,但不是完全散列),因为在这种情况下,将不可能解密它并从中检索用户属性。

但你的问题似乎是试图找到关于持名代币功能的答案:

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

因此,我将尝试解释持有者令牌和刷新令牌是如何工作的:

当用户向服务器请求通过SSL发送用户和密码的令牌时,服务器返回两个东西:Access令牌和Refresh令牌。

访问令牌是一种记名令牌,您必须在所有请求头中添加该令牌,以便作为具体用户进行身份验证。

Authorization: Bearer <access_token>

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

访问令牌的有效期很短(例如。30分钟)。 如果访问令牌的有效期很长,这将是一个问题,因为理论上不可能撤销它。因此,假设一个role=“Admin”的用户更改为“user”。如果用户保留了role="Admin"的旧令牌,他将能够使用Admin权限访问到令牌到期。 这就是为什么访问令牌的有效期很短。

但是,我想到了一个问题。如果一个访问令牌的有效期很短,我们必须在每个短时间内发送用户和密码。这安全吗?不,它不是。我们应该避免它。这时就出现了Refresh令牌来解决这个问题。

刷新令牌存储在DB中,过期时间很长(例如:1个月)。

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

如果用户访问令牌已被破坏,则必须从DB中删除该用户的刷新令牌。这样,令牌将只在访问令牌过期之前有效,因为当黑客试图获得发送刷新令牌的新访问令牌时,此操作将被拒绝。

记名符号是字母、数字、“-”、“”的一次或多次重复。, "_" , "~" , "+" , "/" 其次是0或多个“=”。

2.1. RFC授权请求报头字段(格式为ABNF (Augmented 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没有定义任何编码或解码,而是仅仅定义了 定义在授权部分中可以使用哪些字符 将包含访问令牌的头。

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

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

Does the authorizer have a way of inspecting the URL, identifying the operation, and looking up some role-based access control database to see if it is allowed? If yes and the request comes through, the service can assume it is allowed, and does not need to verify. Is the token an all-or-nothing, so if the token is correct, all operations are allowed? Then the service doesn't need to verify. Does the token mean "this request is allowed, but here is the UUID for the role, you check whether the operation is allowed". Then it's up to the service to look up that role, and see if the operation is allowed.

参考文献

3.6. RFC 5234。可变重复:*规则 2.1增强的BNF

承载令牌是一个b64token字符串,要求如果拥有它,就可以使用它。除此之外,不能保证该字符串在规范中的实际含义是什么。这取决于执行。

5.2. 缓解气候变化的威胁 类的编码或内容,此文档没有指定 令牌;因此,详细的建议有关的手段 保证令牌完整性保护不在本文讨论范围之内 文档。令牌完整性保护必须足够 防止令牌被修改。

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

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

JWT: https://jwt.io/