OAuth2访问令牌中允许使用哪些字符? [英] What characters are allowed in an OAuth2 access token?

查看:71
本文介绍了OAuth2访问令牌中允许使用哪些字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RFC6749 RFC6749的A.12节(原始的OAuth2规范)定义访问令牌格式如下:

A.12."access_token"语法

"access_token"元素在第4.2.2和5.1节中定义:

 访问令牌= 1 * VSCHAR 

ABNF格式中,VSCHAR的意思是:

VSCHAR =%x20-7E

(这基本上是所有可打印的ASCII字符)

但是,在RFC6750(处理OAuth2承载令牌的使用)中,第2.1节似乎为访问令牌设置了更严格的允许字符子集.

Bearer凭证的语法如下:

  b64token = 1 *(ALPHA/DIGIT/-"/./"_"/〜"/"+"/"/")*"="凭据=承载者" 1 * SP b64token 

这是一组限制性更强的字符,仅包括字母数字,六个特殊字符以及用于填充的尾随 = .

我的问题是:

1)这些文件中的哪个在控制?RFC6750是否具有优先权,因为它更具限制性?

2)就狂野"的实际实现而言,访问令牌是否始终限于RFC6750字符集?

3)奖励问题:有谁知道为什么这两个规范在同月发布,涉及如此紧密相关的主题,不同意访问令牌格式?

解决方案

TL; DR:这些标准之间没有冲突.OAuth访问令牌可以通常包含任何可打印的ASCII字符,但是如果访问令牌是Bearer令牌,则必须使用"token64"语法来兼容HTTP/1.1.

RFC 6749,§1.4告诉我们:访问令牌是字符串"和通常对客户端不透明".§A.12将其定义为一个或多个可打印的ASCII字符( [-〜] + (正则表达式).

RFC 6749定义了获得访问令牌的各种方法,但是与如何实际使用访问令牌无关,只是说您要出示".它"发送到资源服务器,该资源服务器必须先验证然后接受或拒绝它.

但是RFC 6749确实要求授权服务器告知客户端令牌类型(另一个字符串),客户端可以使用它确定使用的方式

令牌类型字符串是IANA注册的类型名称(例如 Bearer mac )或供应商URL(例如 http://oauth.example.org/v1 ),尽管该URL只是一个方便命名的标识符,并且不必解析任何内容.

在大多数部署中,令牌类型将为 Bearer ,其语义在RFC 6750中定义.

RFC 6750定义了三种方法(第2.1–2.3节),向资源服务器提供承载访问令牌.推荐方法(该资源服务器必须支持以符合标准)是在HTTP授权标头( [-a-zA-Z0-9._〜+/] + = * (正则表达式).

这与HTTP/1.1规范称为"token68"的内容( RFC 7235§2.1),并且是允许令牌在HTTP授权标头中未加引号的情况所必需的.(至于为什么HTTP/1.1允许使用这些确切的字符,这归结于与HTTP/1.0和Basic身份验证标准有关的历史原因,以及当前和历史HTTP实现的局限性.网络协议是一团糟.)

"b64token"( aka "token68")允许通常与base64编码一起使用的ASCII字符子集,但是(尽管有名称)Bearer令牌 JWT ),但这超出了OAuth或Bearer令牌标准.

RFC 6750并未指出,如果将Bearer访问令牌与其他两种(不推荐使用)方法一起使用,则它必须是b64token,但是考虑到客户端应该能够选择该方法,因此这样做不会做太多赋予它非b64令牌的意义.

其他OAuth令牌类型可能不依赖于在HTTP标头中不加引号的传递(或者它们可能根本不使用HTTP),因此可以自由使用任何可打印的ASCII字符.例如对于客户端不是不透明的令牌类型很有用;例如,我目前正在处理一种设置,其中访问令牌响应看起来像这样:

 <代码> {"access_token":"{\" endpoint \:\" srv8.example.org \,\" session_id \:\" fafc2fd \}","token_type":"http://vendor.example.org/","expires_in":3600,"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"} 

在这里,访问令牌是JSON编码的数据结构,客户端必须对它进行操作(根据与供应商令牌类型相关的规则),以访问受保护的资源.

RFC6749 and RFC6750 seem to disagree with one another about what characters are allowed in an OAuth2 Access Token.

Section A.12 of RFC6749 (the original OAuth2 spec) defines the access token format as follows:

A.12. "access_token" Syntax

The "access_token" element is defined in Sections 4.2.2 and 5.1:

access-token = 1*VSCHAR 

In ABNF format, VSCHAR means:

VSCHAR = %x20-7E

(This is basically all printable ASCII characters)

However, in RFC6750 (which deals with the usage of OAuth2 bearer tokens) Section 2.1 seems to set out a stricter subset of allowed characters for access tokens.

The syntax for Bearer credentials is as follows:

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

So that's a more restrictive set of characters, including only alphanumeric, six special characters, and trailing = for padding.

My questions are:

1) Which of these documents is controlling? Does RFC6750 take precedence because it's more restrictive?

2) In terms of actual implementations "in the wild", are access tokens always limited to the RFC6750 charset?

3) Bonus question: Does anyone know why these two specs published the same month on such closely related topics disagree on the access token format?

解决方案

TL;DR: There's no conflict between the standards. OAuth access tokens can generally contain any printable ASCII character, but if the access token is a Bearer token it must use "token64" syntax to be HTTP/1.1 compliant.

RFC 6749, §1.4 tells us: "An access token is a string" and "usually opaque to the client". §A.12 defines it as one or more printable ASCII characters ([ -~]+ in regex terms).

RFC 6749 defines various methods for obtaining an access token, but doesn't concern itself with how to actually use an access token, other than saying that you "present it" to a resource server, which must validate and then accept or reject it.

But RFC 6749 does require the authorization server to tell the client the token type (another string), which the client can use to determine how the access token is used.

A token type string is either an IANA-registered type name (like Bearer or mac), or a vendor URL (like http://oauth.example.org/v1), though the URL is just a conveniently namespaced identifier, and doesn't have to resolve to anything.

In most deployments, the token type will be Bearer, the semantics of which are defined in RFC 6750.

RFC 6750 defines three methods (§§2.1–2.3) of presenting a Bearer access token to the resource server. The recommended method (which resource servers must support to be standards compliant) is to send it in the HTTP Authorization header (§2.1), in which case the token must be a "b64token" ([-a-zA-Z0-9._~+/]+=* in regex terms).

This matches what the HTTP/1.1 spec calls a "token68" (RFC 7235 §2.1), and is necessary to allow the token to be used unquoted in the HTTP Authorization header. (As for why HTTP/1.1 allows those exact characters, it comes down to historical reasons related to the HTTP/1.0 and Basic authentication standards, as well as limitations in current and historical HTTP implementations. Network protocols are a messy business.)

A "b64token" (aka "token68") permits a subset of ASCII characters usually used with base64 encoding, but (despite the name) the Bearer token does not impose any base64 semantics. It's just an opaque string that the client receives from one server and passes on to another. Implementations may assign semantics to it (e.g. JWT), but that's beyond the OAuth or Bearer token standards.

RFC 6750 doesn't state that a Bearer access token must be a b64token if used with the other two (unrecommended) methods, but given that the client is supposed to be able to choose the method, it wouldn't make much sense to give it a non-b64token token.

Other OAuth token types might not rely on being passed unquoted in an HTTP header (or they might not use HTTP at all), and would thus be free to use any printable ASCII character. This might e.g. be useful for token types that are not opaque to the client; as an example, I'm currently dealing with a setup in which the access token response looks a bit like this:

{
  "access_token": "{\"endpoint\": \"srv8.example.org\", \"session_id\": \"fafc2fd\"}",
  "token_type": "http://vendor.example.org/",
  "expires_in": 3600,
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}

Here, the access token is a JSON-encoded data structure, which the client must act upon (according to rules associated with the vendor token type) to access the protected resource.

这篇关于OAuth2访问令牌中允许使用哪些字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆