3. 客户端私有证书
当与授权服务器进行交互时,客户端使用一个私有证书集合来标识自己,这个证书集合包含一个客户端标识符和用于客户端身份验证的其它一些属性。客户端获得私有证书的方式不在本规范的规定范围之内,不过这通常都包含一个在授权服务器上注册的过程。
考虑到一些客户端的本质特性,在与客户端没有确立信任关系的前提下,授权服务器不应该对客户端密钥的私密性做出任何假设。授权服务器不应该向没有能力对密钥进行秘密保存的客户端分发密钥。
授权服务器可以使用任一合适的私有证书集合和验证机制来对客户端进行身份验证。客户端一定不能在一个请求中使用多个私有证书集合和验证机制。
3.1 客户端密码证书
客户端密码证书使用一个共享的对称密钥来验证客户端。客户端标识符和密码被包含在请求当中,使用[RFC2617]定义的HTTP Basic验证机制,将客户端标识符作为用户名(username)并将客户端密码作为密码(password)来传送。
例如(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=i1WsRn1uB1&
redirect_uri=https://client.example.com/cb
作为可选方式,客户端可以使用下列参数将密码包含在请求体(request body)中:
client_id
必需参数。客户端标识符。
client_secret
必需参数。客户端密钥。
例如(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=s6BhdRkqt3&
client_secret=gX1fBat3bV&code=i1WsRn1uB1&
redirect_uri=https://client.example.com/cb
授权服务器必须能够使用请求参数和HTTP Basic验证协议两种方式接受客户端私有证书。授权服务器可以支持更多适合于密码证书传输的验证机制。
3.2 客户端断言证书
客户端断言证书用于不宜使用密码(明文共享对称密钥)或密码无法为客户端验证提供足够安全性的情况。在这样的情况下,常见的做法是使用诸如HMAC 或数字签名之类不需要发送明文密钥的其它机制。客户端断言证书提供了一种扩展机制,能够使用被授权服务器所支持的某种断言格式进行客户端身份验证。
使用断言需要客户端从一个断言发行方获得一个断言(如SAML[OASIS.saml-core-2.0-os]断言)或自己分发一个断言。断言的格式、获得断言的过程,以及验证断言的方法,由断言发行方和授权服务器定义,不在本规范的规定范围之内。
当使用客户端断言时,客户端传送下列参数:
client_assertion_type
必需参数。由授权服务器定义的断言格式。这个值必须是一个绝对URI。
client_assertion
必需参数。客户端断言。
例如,客户端使用一个SAML 2.0断言发送如下访问令牌请求来验证自己(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=i1WsRn1uB1&
client_assertion=PHNhbWxwOl[...omitted for brevity...]ZT4=&
client_assertion_type=
urn:oasis:names%sAtc:SAML:2.0:assertion&
redirect_uri=https://client.example.com/cb
当使用一个客户端断言和一个授权码获得一个访问令牌的时候,需要一个机制在用于获取授权码的“client_id”参数值和客户端断言之间完成映射。这个机制不在本规范的规定范围之内,但对于与授权码结合使用的任何客户端断言类型都必须明确指明。
对于那些使用客户端断言证书但不包含能够提供下列信息的HMAC或签名值的访问令牌请求,授权服务器必须拒绝响应:
- 指明这个断言是专门分发给当前接收endpoint来处理的(一般是通过一个包含接收endpoint标识符的audience或recipient值)。
- 标识出分发断言的实体(一般是通过一个issuer值)。
- 用一个绝对时间标识出断言在何时过期(一般是通过一个包含UTC日期/时间值的过期值)。授权服务器必须拒绝过期的断言。
4. 获得终端用户授权
在客户端能够访问一个受保护资源之前,它必须首先从终端用户那里获取授权。为了获得终端用户授权,客户端需要将终端用户引导到终端用户授权endpoint。一旦获得授权,终端用户的访问许可会被表示成一个授权码,客户端能够使用它去获取一个访问令牌。
在终端用户授权endpoint上,终端用户首先在授权服务器上完成身份验证,然后允许或者拒绝当前访问请求。授权服务器验证用户的方式(例如,用 户名和密码登录,OpenID,会话cookie)和授权服务器获取终端用户授权的方式,以及是否使用诸如TSL之类的安全通道,不在本规范的规定范围之 内。然而,授权服务器必须要首先验证终端用户的身份。
终端用户授权endpoint的位置能够在服务器文档中找到。终端用户授权endpoint的URI可以按照[RFC3986]第3节的定义包含一个查询参数部分,它们在添加其它参数时必须被保留。
既然对于终端用户授权endpoint的请求会导致用户身份验证和敏感信息的传输,授权服务器应该要求在向终端用户授权endpoint发送请求的时候使用诸如TLS之类的传输层安全机制。
4.1 授权请求
为了将终端用户的user-agent引导到授权服务器,客户端将下列参数添加到终端用户授权endpoint URI的查询参数部分,并使用如[W3C.REC-html401-19991224]所定义的“application/x-www-form-urlencoded”格式构建起一个请求URI,如下定义:
response_type
必需参数。请求的响应中:一个访问令牌、一个授权码,或两者都有。请求访问令牌参数值必须设为“token”,请求授权码参数值必须设为“code”,或者使用参数值为“code_and_token”同时请求两者。授权服务器可能拒绝提供这些响应类型中的一种或多种。
client_id
必需参数。如第3节所述的客户端标识符。
redirect_uri
必需参数,除非通过其它方式在客户端和授权服务器之间已经确定了一个重定向URI。这是当终端用户的授权步骤完成时授权服务器将要把user-agent重定向到的一个绝对URI。授权服务器应该要求客户端预先注册它们的重定向URI。
scope
可选参数。访问请求的作用域,以空格隔开的字符串列表来表示。“scope”参数的值由授权服务器定义。如果这个值包含多个空格隔开的字符串,那么它们的顺序不分先后,而且每个字符串都为请求的作用域增加一个新的访问范围。
state
可选参数。被客户端用来在请求和回调之间维护状态的值,对授权服务器来说是不透明的。授权服务器在将user-agent重定向回客户端时传回这个值。
客户端通过user-agent使用HTTP重定向响应,或者其它可用的方式,将终端用户引导到构建好的URI上。对于终端用户授权endpoint,授权服务器必须支持HTTP的“GET”方法,也可以支持使用“POST”方法。
例如,客户端引导终端用户的user-agent使用传输层安全机制发送下列HTTP请求(换行符只用于显示目的):
GET /authorize?response_type=code&client_id=s6BhdRkqt3&
redirect_uri=https://client.example.com/cb HTTP/1.1
Host: server.example.com
如果客户端已经在授权服务器上预先注册了一个重定向URI,授权服务器必须保证收到的重定向URI与当前客户端标识符所对应的注册URI相匹配。授 权服务器不应该将user-agent重定向到没有注册过的或不信任的URI,以避免endpoint被用作一个公开的转向器。如果没有可用的有效重定向 URI,授权服务器应该将发生的错误报告给用户[[提供如何执行匹配操作的建议]]。
没有值的参数必须被当做它们在请求中不存在一样。授权服务器应该忽略识别不了的请求参数。
授权服务器对请求进行验证以保证所有必需参数都存在并有效。如果请求是无效的,授权服务器将使用重定向URI把user-agent重定向回客户端,并且URI后面加上适当的错误码,如4.3节所述。
授权服务器验证终端用户的身份并获得一个授权决定(通过询问用户或通过其它方式认可)。当一个决定被做出后,授权服务器将终端用户的user- agent引导到客户端提供的重定向URI,这个重定向或者使用HTTP重定向响应,或者通过终端用户user-agent的其它可用的方式。
4.2 授权响应
如果终端用户许可了访问请求,授权服务器会分发一个访问令牌,或一个授权码,或者两者都有,并且通过将下列参数添加到重定向URI将这些分发结果传递给客户端(如下所述)。
code
如果响应类型是“code”或“code_and_token”则是必需的,否则一定不能包含这个参数。表示由授权服务器产生的授权码。授权码应该 在分发后迅速过期,以降低泄露风险。客户端一定不能重用同一个授权码。如果一个授权码被多次使用,授权服务器可能撤销之前基于这个授权码分发的所有令牌。 授权码与客户端标识符和重定向URI相绑定。
access_token
如果响应类型是“token”或“code_and_token”则是必需的,否则一定不能包含这个参数。表示由授权服务器分发的访问令牌。
token_type
如果响应中包含一个访问令牌则是必需的。表示分发的令牌类型。令牌类型告诉客户端一个信息,即当访问一个受保护资源时访问令牌应该如何被使用,如6.1节所述。
expires_in
可选参数。如果包含访问令牌参数,则表示访问令牌生命周期的秒数。例如,“3600”表示自响应被授权服务器产生的时刻起,访问令牌将在一小时后过期。
scope
可选参数。如果包含访问令牌参数,则表示访问令牌的作用域,表示为一个空格隔开的字符串列表。“scope”参数的值由授权服务器定义。如果这个值 包含多个空格隔开的字符串,那么它们的顺序不分先后,而且每个字符串都为请求的作用域增加一个新的访问范围。如果请求到的作用域不同于客户端申请的作用 域,授权服务器应该传回这个参数。
state
如果“state”参数在客户端授权请求中存在,则这个参数是必需的。需要精确地设置成从客户端接收到的值。
授权服务器在重定向URI上添加参数的方式取决于客户端在授权请求中请求的响应类型,由“response_type”参数指定。
如果响应类型是“code”,授权服务器使用如[W3C.REC-html401-19991224]所定义的“application/x-www-form-urlencoded”格式添加参数到重定向URI的查询参数部分。
例如,授权服务器通过发送下列HTTP响应将终端用户的user-agent进行重定向:
HTTP/1.1 302 Found
如果响应类型是“code”或“code_and_token”,授权服务器使用如[W3C.REC-html401-19991224]所定义的“application/x-www-form-urlencoded”格式添加参数到重定向URI的分段参数部分。
例如,授权服务器通过发送下列HTTP响应将终端用户的user-agent进行重定向(URI换行符只用于显示目的):
HTTP/1.1 302 Found
token_type=example&expires_in=3600
客户端应该忽略无法识别的响应参数。从授权服务器接收到的令牌和其它参数值的大小,本规范未作定义。客户端应该避免对参数值大小做任何假设。服务器应该对它们所分发的任何参数值的期望大小做出文档说明。
4.3 错误响应
如果终端用户拒绝了访问请求,或者由于除了缺少或无效重定向URI之外的其它原因而导致请求失败,授权服务器使用如[W3C.REC- html401-19991224]所定义的“application/x-www-form-urlencoded”格式添加下列参数到重定向URI的 查询参数部分以通知客户端:
error
必需参数。如4.3.1节所述的一个错误码。
error_description
可选参数。提供额外信息的一段人类可读的文字,用来帮助理解和解决发生的错误。
error_uri
可选参数。指明了一个人类可读的网页URI,带有关于错误的信息,用来为终端用户提供与错误有关的额外信息。
state
如果“state”参数在客户端授权请求中存在,则这个参数是必需的。需要精确地设置成从客户端接收到的值。
例如,授权服务器通过发送下列HTTP响应将终端用户的user-agent进行重定向:
HTTP/1.1 302 Found
如果由于缺少或无效重定向URI而导致请求失败,授权服务器应该通知终端用户这个错误,而一定不能将终端用户的user-agent重定向到这个无效的重定向URI。
4.3.1 错误码
授权服务器在错误响应中包含下列错误码之一:
invalid_request
请求缺少某个必需参数,包含一个不支持的参数或参数值,或者格式不正确。
invalid_client
提供的客户端标识符是无效的。
unauthorized_client
客户端没有权限使用该请求的响应类型。
redirect_uri_mismatch
提供的重定向URI与预先注册的值不匹配。
access_denied
终端用户或授权服务器拒绝了请求。
unsupported_response_type
请求的响应类型不为授权服务器所支持。
invalid_scope
请求的作用域是无效的、未知的,或格式不正确的。
[[增加扩展错误码的机制]]
5. 获取访问令牌
客户端通过在授权服务器上验证并出示它的访问许可(表示成授权码、资源拥有者私有证书、断言或刷新令牌的形式)来获取一个访问令牌。
既然对于令牌endpoint的请求会导致在HTTP请求和响应中传输明文证书,授权服务器必需要求在向令牌endpoint发送请求的时候使用传输层安全机制。服务器必需支持[RFC5246]所定义的TLS 1.2,并且可能支持额外的传输层安全机制。
客户端通过向令牌endpoint发送一个HTTP POST请求来获取一个访问令牌。令牌endpoint的位置能够在服务器文档中找到。令牌endpoint URI可能包含一个查询参数部分。
客户端通过在请求中添加客户端私有证书与授权服务器进行验证,如第3节所述。当客户端标识符不重要的时候(例如匿名客户端),或当客户端标识符通过其它方式确定的时候(例如使用一个断言访问许可),授权服务器可能允许不经验证的访问令牌请求。
客户端通过在HTTP请求的entity-body中使用“application/x-www-form-urlencoded”格式包含下列参数,来构建请求:
grant_type
必需参数。在请求中所包含的访问许可类型。它的值必须是“authorization_code”、“password”、“refresh_token”、“client_credentials”或一个用来标识被授权服务器所支持的断言类型的绝对URI。
scope
可选参数。访问请求的作用域,表达为一个由空格隔开的字符串列表。“scope”参数的值由授权服务器定义。如果这个值包含多个空格隔开的字符串, 那么它们的顺序不分先后,而且每个字符串都为请求的作用域增加一个新的访问范围。如果使用的访问许可已经代表了一个许可作用域(例如,授权码、断言),那 么请求的作用域必须等于或少于之前许可的作用域,如果缺少这个参数就认为是等于之前的许可作用域。
另外,对于5.1节列出的某个访问许可类型,客户端必须包含合适的参数。
没有值的参数必须被当做它们在请求中不存在一样。授权服务器应该忽略识别不了的请求参数。
5.1 访问许可类型
客户端使用一个授权码、资源拥有者密码证书、客户端私有证书、刷新令牌或断言来请求一个访问许可。
5.1.1 授权码
客户端使用“authorization_code”访问许可类型和下列参数传入授权码:
code
必需参数。从授权服务器接收到的授权码。
redirect_uri
必需参数。在最初请求中使用的重定向URI。
例如,客户端通过如第3节所述的“client_secret”参数包含客户端私有证书,并使用传输层安全机制,来发送下列HTTP请求(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=s6BhdRkqt3&
client_secret=gX1fBat3bV&code=i1WsRn1uB1&
redirect_uri=https://client.example.com/cb
授权服务器必须:
- 验证客户端私有证书(如果存在)并保证它们与授权码匹配。
- 验证授权码和重定向URI都是有效的,并且与存储的关联关系相匹配。
如果请求有效,授权服务器分发一个成功响应,如5.2节所述。
5.1.2 资源拥有者密码证书
客户端使用“password”访问许可类型和下列参数传入资源拥有者密码证书:[[增加对于用户名和密码的国际化考虑]]
username
必需参数。资源拥有者的用户名。
password
必需参数。资源拥有者的密码。
例如,客户端通过如第3节所述的“client_secret”参数包含客户端私有证书,并使用传输层安全机制,来发送下列HTTP请求(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=password&client_id=s6BhdRkqt3&
client_secret=47HDu8s&username=johndoe&password=A3ddj3w
授权服务器必须验证客户端私有证书(如果存在)和终端用户私有证书,而且如果发现有效则必须发布一个访问令牌响应,如5.2节所述。
5.1.3 客户端私有证书
客户端可以仅仅使用它的客户端私有证书来请求一个访问令牌,即使用“client_credentials”访问许可类型。当省略一个显式的访问许 可时,客户端是在请求访问它所控制的受保护资源,或另一个资源拥有者之前与授权服务器约定好的受保护资源(约定方式不在本规范的规定范围之内)。
5.1.4 刷新令牌
客户端使用“refresh_token”访问许可类型和下列参数传入刷新令牌:
refresh_token
必需参数。与待刷新的访问令牌相关联的刷新令牌。
例如,客户端通过如第3节所述的“client_secret”参数包含客户端私有证书,并使用传输层安全机制,来发送下列HTTP请求(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&client_id=s6BhdRkqt3&
client_secret=8eSEIpnqmM&refresh_token=n4E9O119d
授权服务器必须验证客户端私有证书(如果存在),验证刷新令牌是否有效,以及验证资源拥有者的授权是否仍然有效。如果请求有效,授权服务器则发布一 个访问令牌响应,如5.2节所述。授权服务器可以发布一个新的刷新令牌,在这种情况下,客户端必须丢弃旧的刷新令牌并且用新的访问令牌替换。
5.1.5 断言
客户端使用一个绝对URI(由授权服务器定义)作为“grant_type”参数的值指定断言格式,并添加下列参数,来传入一个断言:
assertion
必需参数。断言。
例如,客户端使用传输层安全机制来发送下列HTTP请求,且客户端验证通过断言来完成(换行符只用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:oasis:names:tc:SAML:2.0:assertion&
assertion=PHNhbWxwOl[...omitted for brevity...]ZT4=
授权服务器必须验证客户端私有证书(如果存在)和断言,而且如果发现有效则必须发布一个访问令牌响应,如5.2节所述。授权服务器不应该分发一个刷新令牌(而是应该要求客户端使用相同的或新的断言)。
授权服务器应该分发具有有限生命周期的访问令牌,并且要求客户端使用仍然有效的同一个断言来请求新的访问令牌,从而完成对令牌的刷新。
5.2 访问令牌响应
在接收到并验证过来自客户端的一个有效且经授权的访问令牌请求之后,授权服务器分发访问令牌和可选的刷新令牌,并且通过一个200(OK)状态码在HTTP响应的entity body中添加下列参数来构造响应:
令牌响应包含下列参数:
access_token
必需参数。由授权服务器分发的访问令牌。
token_type
必需参数。分发的令牌类型。令牌类型告诉客户端一个信息,即当访问一个受保护资源时访问令牌应该如何被使用,如6.1节所述。
expires_in
可选参数。访问令牌生命周期的秒数。例如,“3600”表示自响应被授权服务器产生的时刻起,访问令牌将在一小时后过期。
refresh_token
可选参数。用来获取新的访问令牌的刷新令牌,如5.1.4节所述使用相同的终端用户访问许可。当访问许可类型是一个断言或一个客户端私有证书集合时,授权服务器不应该分发一个刷新令牌。
scope
可选参数。访问令牌的作用域,表示为一个空格隔开的字符串列表。“scope”参数的值由授权服务器定义。如果这个值包含多个空格隔开的字符串,那 么它们的顺序不分先后,而且每个字符串都为请求的作用域增加一个新的访问范围。如果请求到的作用域不同于客户端申请的作用域,授权服务器应该传回这个参 数。
参数包含在HTTP响应的entity body中,使用[RFC4627]定义的“application/json”媒体类型。通过在最高结构层次上添加每个参数,将它们序列化成一个JSON结构。参数名和字符串值都表示成JSON字符串。数字值表示成JSON数字。
在任何包含令牌、密钥或其它敏感信息的响应中,授权服务器必须在“Cache-Control”响应头部字段中传入一个“no-store”的值。
例如:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token":"SlAV32hkKG",
"token_type":"example",
"expires_in":3600,
"refresh_token":"8xLOxBtZp8"
}
客户端应该忽略无法识别的响应参数。从授权服务器接收到的令牌和其它参数值的大小,本规范未作定义。客户端应该避免对参数值大小做任何假设。服务器应该对它们所分发的任何参数值的期望大小做出文档说明。
5.3 错误响应
如果令牌请求是无效的或未经授权的,授权服务器通过在HTTP响应的entity body中添加下列参数并使用“application/json”媒体类型来构造响应:
error
必需参数。如4.3.1节所述的一个错误码。
error_description
可选参数。提供额外信息的一段人类可读的文字,用来帮助理解和解决发生的错误。
error_uri
可选参数。指明了一个人类可读的网页URI,带有关于错误的信息,用来为终端用户提供与错误有关的额外信息。
例如:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error":"invalid_request"
}
如果客户端通过“Authorization”请求头部字段使用HTTP验证机制这种方式提供了无效的私有证书,那么授权服务器必须用HTTP 401(Unauthorized)状态码进行响应。否则,授权服务器应该用HTTP 400(Bad Request)状态码进行响应。
5.3.1 错误码
授权服务器在错误响应中传回下列错误码之一:
invalid_request
请求缺少某个必需参数,包含一个不支持的参数或参数值,参数重复,包含多个私有证书,使用了多种验证客户端的机制,或者请求格式不正确。
invalid_client
提供的客户端标识符是无效的,客户端验证失败,客户端不包含私有证书,提供了多个客户端私有证书,或使用了不支持的证书类型。
unauthorized_client
经过验证的客户端没有权限使用提供的访问许可类型。
invalid_grant
提供的访问许可是无效的、过期的或已撤销的(例如,无效的断言,过期的授权令牌,错误的终端用户密码证书,或者不匹配的授权码和重定向URI)。
unsupported_grant_type
包含的访问许可——它的类型或其它属性——不被授权服务器所支持。
invalid_scope
请求的作用域是无效的、未知的、格式不正确的,或超出了之前许可的作用域。
[[增加扩展错误码的机制]]
6. 访问受保护资源
客户端通过向资源服务器出示一个访问令牌来访问受保护资源。资源服务器必须验证访问令牌,保证它没有过期并且它的作用域覆盖了请求的资源。被资源服务器用来验证访问令牌的方式不在本规范的规定范围之内,但是它通常需要在资源服务器和授权服务器之间进行交互或配合。
客户端利用访问令牌来验证资源服务器的方式取决于由授权服务器分发的访问令牌类型。
6.1 访问令牌类型
[[增加令牌类型的解释,可能包含指定其它规范的链接]]
6.2 WWW-Authenticate响应头部字段
如果对于受保护资源的请求不包含验证证书,包含一个无效的访问令牌,或格式不正确,那么资源服务器必须包含一个HTTP “WWW-Authenticate”响应头部字段。这个“WWW-Authenticate”头部字段使用[RFC2617]定义的框架,如下所示:
challenge = "OAuth2" [ RWS 1#param ]
param = scope /
error / error-desc / error-uri /
( token "=" ( token / quoted-string ) )
scope = "scope" "=" <"> scope-v *( SP scope-v ) <">
scope-v = 1*quoted-char
quoted-char = ALPHA / DIGIT /
"!" / "#" / "$" / "%" / "&" / "'" / "(" / ")" /
"*" / "+" / "-" / "." / "/" / ":" / "<" / "=" /
">" / "?" / "@" / "[" / "]" / "^" / "_" / "`" /
"{" / "|" / "}" / "~" / "" / "," / ";"
error = "error" "=" quoted-string
error-desc = "error_description" "=" quoted-string
error-uri = "error_uri" = <"> URI-reference <">
“scope”属性是一个空格隔开的作用域值的列表,表明了为了访问受保护资源所需要访问令牌作用域。“scope”属性一定不能出现多次。
如果对于受保护资源的请求包含一个访问令牌并且验证失败了,那么资源服务器应该包含“error”属性来向客户端提供为何访问请求被拒绝的原因。参 数值在6.2.1中描述。另外,资源服务器可能包含“error_description”属性来提供一个人类可读的解释,或者包含“error- uri”属性用一个绝对URI来指定一个用于解释错误的人类可读的网页。“error”、“error_description”和“error- uri”属性一定不能出现多次。
例如,对于一个缺少验证的受保护资源请求的响应:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: OAuth2
对于一个使用过期访问令牌尝试验证的受保护资源请求的响应:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: OAuth2
error="invalid_token",
error_description="The access token expired"
6.2.1 错误码
当一个请求失败时,资源服务器使用恰当的HTTP状态码(典型的如400、401或403)进行响应,并且在响应中包含下列错误码之一:
invalid_request
请求缺少某个必需参数,包含一个不支持的参数或参数值,参数重复,使用多种方式包含访问令牌,或者请求格式不正确。资源服务器应该使用HTTP 400(Bad Request)状态码进行响应。
invalid_token
提供的访问令牌是过期的、已撤销的、格式不正确的,或由于其它原因是无效的。资源服务器应该使用HTTP 401(Unauthorized)状态码进行响应。客户端可能请求一个新的访问令牌并重试受保护资源请求。
insufficient_scope
请求需要比访问令牌所提供的权限更高的权限。资源服务器应该使用HTTP 403(Forbidden)状态码进行响应并且包含“scope”属性,带上访问该受保护资源必需的作用域。
[[增加扩展错误码的机制]]
如果请求中缺少任何验证信息(即客户端没有意识到验证是必需的或尝试使用一个不支持的验证方法),那么资源服务器不应该包含一个错误码和其它错误信息。
例如:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: OAuth2
7. 扩展
7.1 定义新的客户端证书类型
[[待定]]
7.2 定义新的Endpoint参数
希望在终端用户授权endpoint和令牌endpoint上定义新的请求和响应参数的应用,应该使用下列两种方式之一:在参数注册表中注册(遵从9.1节描述的流程),或使用“x_”参数名前缀。
使用“x_”参数名前缀的参数必须局限于那些不会被广泛应用的针对厂商特性的扩展,并且特定于授权服务器使用场景的实现细节。所有其它参数必须被注册,并且一定不能使用“x_”参数名前缀。
参数名必须遵从param-name的ABNF,并且参数值语法必须被规范地定义(例如,使用ABNF,或者引用到现存参数的语法)。
param-name = 1*name-char
name-char = "-" / "." / "_" / DIGIT / ALPHA
7.3 定义新的头部字段参数
希望在OAuth “WWW-Authenticate”头部字段中定义新参数的应用必须在参数注册表中进行注册,遵从9.1节描述的流程。
参数名必须遵从param-name的ABNF并且不能以“x_”开头。参数值必须遵从param-value的ABNF并且语法必须被规范地定义(例如,使用ABNF,或者引用到现存参数的语法)。
param-value = quoted-value | quoted-string
7.4 定义新的访问许可类型
断言访问许可类型允许授权服务器接受其它未规定的访问许可。希望定义其它访问许可类型的应用能够通过利用新的或现存的断言类型和格式进行实现。
8. 安全考虑
[[待定]]
9. IANA事项
9.1 OAuth参数注册表
本文档设立参数注册表。
用于终端用户授权endpoint的请求、终端用户授权endpoint的响应、令牌endpoint的请求、令牌endpoint的响应或 “WWW-Authenticate”头部字段的多余参数,在一个或多个“指派专家”(由IESG或他们的代理机构指定)的指导下进行注册,遵从所需的规 范(使用[RFC5226]的术语)。然而,为了允许在发布之前对值进行分配,“指派专家”们一旦认同这样的一个规范能够发布,可能就立即批准注册。
注册请求应该发送给[待定]@ietf.org邮件组进行评审和讨论,使用恰当的标题(如“Request for parameter: example”)。[[RFC-EDITOR注解:邮件组名称应该在与IESG和IANA磋商后确定。建议名称:oauth-ext-review。]]
在14天之内,“指派专家”们会批准或拒绝注册请求,并将结果告知邮件组和IANA。拒绝的决定应该包含一个解释,并且,如果可行的话,应该包含如何进行修改的建议。在21天以上未确定的注册请求会交由IESG处理(使用
iesg@iesg.org邮件组)。
9.1.1 注册模板
Parameter name: 请求的名称(例如“example”)。
Parameter usage location: 参数能够被使用的位置。可能的位置包括:终端用户授权endpoint的请求、终端用户授权endpoint的响应、令牌endpoint的请求、令牌endpoint的响应或“WWW-Authenticate”头部字段。
Change controller: 对于标准轨道的RFC,写明“IETF”。对于其它规范,使用负责机构的名称。其它细节(例如,邮编地址,电子邮件地址,主页URI)也可以包含。
Specification document(s): 对规定参数的文档引用,可取的方式是包含一个能够获取到文档拷贝的URI。对于相关章节的标示也可以包含,但不是必需的。
Related information: 可选地,对于包含更多相关信息的额外文档的引述。
9.1.2 例子
下面是对于本规范定义的“scope”参数的参数注册请求:
Parameter name: scope
Parameter usage location: The end-user authorization endpoint
request, the end-user authorization endpoint response, the token
endpoint request, the token endpoint response, and the
"WWW-Authenticate" header field.
Change controller: IETF
Specification document(s): [[ this document ]]
Related information: None
附录 翻译略。