OAuth 2.0承载令牌到底是什么?


169

根据RFC6750- OAuth 2.0授权框架:承载令牌用法,承载令牌为:

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

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

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

感谢您的指导。


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

Answers:


145

承载令牌
一种具有所有权的安全令牌,拥有该令牌的任何一方(“承载者”)都可以使用拥有该令牌的任何其他方可以使用的任何方式的令牌。使用承载令牌不需要承载者证明拥有加密密钥材料(资产证明)。

承载令牌是由身份验证服务器为您创建的。当用户对您的应用程序(客户端)进行身份验证时,身份验证服务器将为您生成令牌。承载令牌是OAuth 2.0使用的访问令牌的主要类型。承载令牌基本上说“给此令牌访问的承载”。

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

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

Google Refresh令牌看起来像这样: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"是承载授权令牌。这是认证服务器生成的密码令牌。随操作发送的所有承载令牌都有问题字段,而受众字段将发件人域指定为https://形式的URL。例如,如果电子邮件来自noreply@example.com,则受众为https://example.com

如果使用承载令牌,请验证请求是否来自身份验证服务器,并且是否针对发件人域。如果令牌未验证,则服务应使用HTTP响应代码401(未授权)来响应请求。

承载令牌是OAuth V2标准的一部分,并被许多API广泛采用。


2
@Xavier Egea Bearer令牌基本上是您的刷新令牌,而不是访问令牌。
Akhil Nambiar'9

13
不记名令牌并不表示其刷新令牌@AqeelSmith tools.ietf.org/html/rfc6750#section-6.1.1
Suman Kundu

9
第一段暗示承载令牌是刷新令牌,而不是访问令牌。不是这种情况。来自承载令牌规范“该规范描述了当OAuth访问令牌是承载令牌时如何发出受保护的资源请求。” RFC6750
Daniel Daniel

8
阅读答案后,我还认为承载令牌和刷新令牌是相同的。答案应该更新以澄清这一点。
KurioZ7 '19

2
这个答案很有误导性。承载令牌不是“刷新令牌”,如该答案的初始声明所述。请纠正。
think01

67

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

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

假设我正在实现授权提供者,我可以为承载令牌提供任何类型的字符串吗?可以是随机字符串吗?它必须是某些属性的base64编码吗?应该将其散列吗?

因此,我将尝试解释Bearer令牌和Refresh令牌的工作方式:

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

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

Authorization: Bearer <access_token>

访问令牌是具有所需的所有用户属性,声明和角色的加密字符串。(如果添加更多角色或声明,则可以检查令牌的大小是否增加)。资源服务器一旦收到访问令牌,便可以对其进行解密并读取这些用户属性。这样,将与所有应用程序一起对用户进行验证和授予。

访问令牌的有效期限很短(即30分钟)。如果访问令牌的有效期很长,那将是一个问题,因为从理论上讲,不可能撤销它。因此,假设一个角色为角色“ Admin”的用户更改为“ User”。如果用户使用角色=“ Admin”保留旧令牌,则他将可以使用Admin权限访问令牌直到令牌到期。这就是访问令牌的有效期短的原因。

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

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

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

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


2
我不理解这一部分:“授权服务器一旦收到访问令牌,便可以对其进行解密并读取这些用户属性。这样,将在所有应用程序中对用户进行验证和授予权限”。授权服务器不是授予访问令牌但不接收访问令牌的服务器吗?我正在努力解决这个问题,许多示例使“授权”服务器和“资源”服务器之间有明显区别。我了解的是,您是从授权服务器获取访问令牌,然后将它与您对资源服务器的每个请求一起传递的?
kivikall

1
@kivikall你是对的。我已经在答案中更改了它。资源服务器在每个请求中接收令牌(授权服务器在令牌创建过程中已加密的令牌)并将其解密。
Xavier Egea

1
@kivikall实际上,解密令牌应该与授权有关,因此它应该属于授权服务器。这就是为什么在答案中写它的原因。但是实际上,这意味着在每个请求中,您都必须通过授权服务器验证收到的令牌(可能执行另一个请求)。因此,为避免性能损失,最好提供一些功能以将令牌解密到资源服务器。检查下一个环节:stackoverflow.com/questions/12296017/...
泽维尔EGEA

但是,在每个请求上,资源服务器都应检查所提供的AccessToken是否对授权服务器有效。因此,如果角色更改,则更改可以立即由Auth Server反映出来,对吗?另外,如果AccessToken被破坏了,为什么还要删除RefreshToken?无法基于AccessToken计算RefreshToken,因此当过期时,黑客再次被阻止。
普通话

如我所说,访问令牌包含用户信息,例如角色。如果用户角色更改,则此更改将在当前令牌到期时反映在下一个令牌中。这意味着在短时间内(直到访问令牌到期),用户将保留相同的角色,并且由于令牌仍然有效,因此Auth Server会允许该角色。关于第二个问题,删除刷新令牌会使用户再次插入其凭据。如果访问令牌受损,这就是我们想要的。在其他情况下,黑客可以被授权直到刷新令牌到期(例如1个月)
Xavier Egea

8

不记名令牌是字母,数字,“-”,“”的一个或多个重复。,“ _”,“〜”,“ +”,“ /”,后跟0个或多个“ =”。

RFC 6750 2.1。授权请求标头字段(格式为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标头部分使用哪些字符。

参考资料


您根本不解释Bearer令牌的目的。
Jaime Hablutzel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.