5. 分发访问令牌
如果访问令牌请求时有效地和被授权的,授权服务器分发一个访问令牌和可选的刷新令牌,如5.1所述。如果请求客户认证失败或者无效,授权服务器返回一个错误响应如5.2所述。
5.1 成功的响应
授权服务器分发一个访问令牌和可选的刷新令牌,通过添加下面的参数到HTTP实体来构造响应。响应由200个状态码。
access_token
REQUIRED. 访问令牌被授权服务器分发。
token_type
REQUIRED. 令牌的类型,值区分大小写。
expires_in
OPTIONAL. 访问令牌的生命周期以秒计时。例如,值“3600”表示授权令牌在响应生成时之后的一个小时内过期。
refresh-token
OPTIONAL. 被用于接收新的访问令牌的刷新令牌使用相同的权限授予,如6章。
Scope
OPTIONAL. 访问令牌的范围如3.3所述。
参数被包含在使用“application/json”介质类型的HTTP响应实体内。通过在
最高层次结构添加每一个参数将参数序列化为JSON结构。参数名和字符串值被包含在JSON字符串内。数值为JSON值。参数顺序不重要,可以有所不同。
授权服务器必须包含http“Cache-Control”响应头,跟包含了令牌、凭证或其他敏感信息的响应一样,这个响应头里包含“no-store”的值。同时,该授权服务器也要有包含了“no-cache”值的“Pragma”响应头。
例如:
HTTP/1.1 200 OK
Content-Type:application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
Client应该忽视不识别的响应参数,令牌的大小和从授权服务器收到的其它值是没被定义的。Client应该避免对值大小做假设,授权服务器应该将这些分发的值大小归档。
5.2 错误响应
授权服务器响应一个HTTP 400 状态码,包括下列参数:
error
REQUIRED 来自以下的简单错误码:
invalid_request: 请求丢失了必要的参数,包括一个不被支持的参数值,重复的参数,多重凭据,使用超过一个机制验证客户端,或者是其它格式。
invalid_client
客户验证失败(比如,未知客户端,没有包含的客户端认证,或者不支持的认证方法)。认证服务器可能返回一个HTTP 401(未认证)状态码来说明,这是被HTTP 认证计划所支持的。如果client 尝试通过“Authorization ”请求头字段认证,授权服务器必须响应一个 HTTP 401(未认证) 的状态码,包括“WWW-Authenticate”响应头字段匹配客户端使用的授权计划。
invalid_grant
被支持的权限授予(比如,授权码,资源所有者凭证,客户凭证)是无效的,过期的,撤销的,不匹配用于认证请求的重定向UR,或者被分发给其它客户
unauthorized_client
授权客户没被认证就使用这个权限授予类型。
Unsupported-grant_type
权限授予类型不被授权服务器支持。
Invalid_scope
请求的范围是无效的,位置的,不合格式的,或者超过了资源所有者授予的范围。
error_description
OPTIONAL. 一个提供更多信息的人类可读的UTF-8 编码文本,用于帮助客户端开发,使我们了解所发生的错误
error_uri
OPTIONAL 提供识别有关错误信息,供人参阅的网页URI。提供客户端开发和有关错误的其他信息
参数被包含在使用“application/json”介质类型的HTTP响应实体内。通过在
最高层次结构添加每一个参数将参数序列化为JSON结构。参数名和字符串值被包含在JSON字符串内。数值为JSON值。参数顺序不重要,可以有所不同。
For example:
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"error":"invalid_request"
}
6 刷新访问令牌
如果授权服务器分发一个刷新令牌给客户端,客户端用过增加下面的参数到HTTP 请求实体来做出对令牌端点刷新请求。
grant_type
REQUIRED. “refresh_token”必须被赋值。
refresh_token
REQUIRED. 发送给客户端的刷新令牌
Scope
OPTIONAL. 访问请求的令牌,如3.3所述。请求的反问必须不能包括任何非 资源所有者授权的范围。如果忽略被看成与资源所有原始授权等价的。
因为刷新令牌通常是持续久的凭证,用于请求额外访问令牌,刷新令牌被绑
定到它被分发的客户端。如果客户类型是保密的或者客户被分发客户凭据,client必须与授权服务器验证,如3.2.1所述。
例如,client使用传输层安全机制做出如下HTTP请求:
POST /token HTTP/1.1
Host: server.example.com
Authorization: BasicczZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type:application/x-www-form-urlencoded;charset=UTF-8
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
授权服务器必须:
(a) 要求客户验证客户凭证或者任何被分发了客户凭证的客户。
(b) 如果客户认证被包含就验证客户,确保刷新令牌被分发给授权客户,验证刷新令牌。
如果有效和授权的,授权服务器分发一个访问令牌如5.1所述。如果请求验证失败或者无效,授权服务器返回一个错误响应,如5.2所述。
授权服务器可能分发一个刷新令牌,这样客户端必须丢弃旧的刷新令牌,然后用新的去替换。授权服务器可能在分发了新的刷新令牌给客户后撤销旧的刷新令牌。如果一个刷新令牌被分发,刷新令牌的范围必须被客户端标示在请求中。
7 访问受保护资源
客户通过提交访问令牌给资源所有者访问受保护资源。资源服务器必须验证访问令牌,以确保它没暴露还有它的反问包含了所请求的资源。被资源服务器用来验证访问令牌的方法超过了本规范的范围。但是大概的涉及了一个在资源服务器与授权服务器间的交互和合作。
7.1 访问令牌类型
访问令牌类型提供了客户端成功使用访问令牌做出受保护资源访问的信息。客户端一定不能用访问令牌,如果它不理解或者不信任令牌类型。
例如,“bearer”令牌类型被用于简单包含令牌字符串在请求中:
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer7Fjfp0ZBr1KtDRbnfVdmIw
而“mac”令牌类型被用来分发一个和访问令牌一起的MAC KEY,这个访问令牌被用来标记HTTP 请求中的某些组件:
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: MACid="h480djs93hd8",
nonce="274312:dj83hs9s",
mac="kDZvddkndxvhGRXZhvuDjEWhGeE="
以上的例子仅用于说明目的。建议开发者在使用前参考[I-D.ietf-oauth-v2-bearer]和[I-D.ietf-oauth-v2-http-mac]这两份规范。
每个访问令牌类型定义指定的附加属性和“access_token”响应参数一起送到客户端。它也定义HTTP 授权方法,用于包括访问令牌当做出对受保护资源请求时。
8.可扩展性
8.1 定义访问令牌类型
访问令牌类型可以被定义为下面两种方法中的一个:在访问令牌注册表中注册,或者使用独一无二的绝对路径作为他的名字。
利用一个URI名字的类型应该被限制在具体供应商的实现,不普遍适用,并具体到他们使用的资源服务器的实施细则。
所有其他类型必须被注册。类型名称必须符合类型-名的ABNF. 如果类型定义包括一个新的HTTP 授权计划, 类型名应该HTTP 授权计划名相同。令牌类型“example”被保留用于例子中。
type-name = 1*name-char
name-char = "-" / "." /"_" / DIGIT / ALPHA
8.2 定义新端点参数
用于授权端点或者令牌端点的新请求或者响应参数在参数注册表中被定义和注册。
参数名必须符合参数-名ABNF ,参数值语法必须被良好定义(例如,使用ABNF,或者一个现有的参数语法的引用)。
param-name = 1*name-char
name-char = "-" / "." / "_" / DIGIT / ALPHA
为注册的供应商特定的参数扩展是通常不被使用的,并具体到他们使用的授权服务器的实施细则,利用供应商特定的前缀,这是不太可能与其他注册价冲突。
8.3 定义新的权限授予类型
新的权限授予类型可以通过分配他们一个独一无二的绝对路径被定义。如果扩展授权类型需要额外的令牌端点参数,他们必须被注册在oAuth参数注册表里,如11.2节所述。
8.4 定义新的授权端点响应类型
新的用于授权端点响应的类型是被定义和注册在授权端点资源类型注册表里面的。响应类型名称必须与响应-名 ABNF相同。
response-type = response-name*( SP response-name )
response-name = 1*response-char
response-char = "_" / DIGIT / ALPHA
如果一个响应类型包括一个或更多的空格,它被作为空格分隔列表值被比较,值的顺序不重要。只有一个值的顺序可以被注册,它携带了所有其他相同集下的值的安排。
例如,响应类型“token_code” 在这个规范里面没被说明。但是一个扩展可以定义和注册“token_code”响应类型。一旦注册了,相同的组合不能被注册为“code_toen”, 但是两个值可以被用来表示相同的响应类型。
8.5 定义额外的错误码
在协议扩展的案例中(例如,访问令牌类型,扩展参数,或者扩展授权类型)需要额外逇的错误码用于授权码授权错误响应,隐式授权错误响应,或者令牌错误响应,这种错误码可以被定义。
扩展错误码必须被注册,如果他们用于连接的扩展是一个注册的访问令牌类型,一个注册的端点参数,或者一个扩展授权类型。用于未注册的扩展的错误码可能被注册。
错误码必须符合error-code ABNF,而且应该成为识别名的前缀。例如,一个错误识别一个无效的值设置为扩展参数“example”应该被命名为“example_invalid”。
error-code = ALPHA *error-char
error-char = "-" / "." /"_" / DIGIT / ALPHA
9 本地应用
本地应用是客户端安装和直接在资源所有的设备上的(比如,桌面应用,本地移动应用)。本地应用可能需要特别考虑有关安全,平台功能和最终用户体验。
授权端点需要客户端与资源所有者的用户代理交互。本地应用可以调用一个扩展的用户代理或者在应用程序中嵌入一个用户代理。
例如:
(a) 扩展用户代理 --- 本地应用可以捕捉来自授权服务器的响应,该响应使用操作系用的注册计划的重定向URI来调用客户端作处理器,手动复制粘贴凭证,运行本地的web服务,安装用户代理扩展,或者在客户的控制下提供一个重定向URI标示一个服务器托管的资源,这反过来使响应对本地应用有效。
(b) 嵌入用户代理 --- 本地应用通过直接与嵌入的用户代理交流来获取响应,用户代理检测资源负载的排放,或者访问用户代理的cookies存贮的状态变化。
当在选择一个扩展或者嵌入用户代理时,开发者需要考虑:
(A) 扩展用户代理可能提升完成速度当资源所有者可能已经有一个激活的任务,授权服务器移除重认证的需要。它提供一个熟悉的最终用户体验和功能。资源所有者可能也依赖用户代理功能或者扩展来协助认证(比如,password maneger,2-factor device reader)
(B) 嵌入用户代理可能提供更好的可用性,应为他们消除切换上下文和打开新窗口的需要。
(C) 嵌入用户代理构成了安全挑战,因为资源所有者在一个未识别窗口中授权,且窗口在大多数用户代理是时没有访问虚拟保护的。嵌入用户代理教会最终用户信任未识别的请求来认证(使钓鱼攻击更容易执行)。
当在选择隐式授权类型和授权码授权类型时,下面是要被考虑的问题:
(A) 使用授权码授权类型的本地应用应该不使用客户凭证,由于本地应用没有能力保持客户端凭证的保密性。
(B) 当使用隐式授权类型流时,一个刷新令牌不被返回,一旦访问令牌曝光,令牌需要重复认证过程。