3. Protocol Endpoints
-
协议端点
授权过程使用两个授权服务器端点 (HTTP 资源):
o Authorization endpoint - 客户端通过用户代理重定向从资源所有者获得授权时使用.
o Token endpoint - 客户端通常在进行客户端认证的同时, 使用该端点将授权许可交换为访问令牌.
以及一个客户端端点:
o Redirection endpoint - 授权服务器通过资源所有者的用户代理, 使用该端点向客户端返回包含授权凭据的响应.
并非每种授权许可类型都会使用这两个端点. 扩展许可类型可以根据需要定义额外端点.
3.1. 授权端点
授权端点用于与资源所有者交互并获得授权许可. 授权服务器必须首先验证资源所有者的身份. 授权服务器认证资源所有者的方式 (例如用户名和密码登录, 会话 Cookie) 不在本规范范围内.
客户端如何获得授权端点位置不在本规范范围内, 但该位置通常会在服务文档中提供.
端点 URI 可以包含按 Appendix B 规定的 "application/x-www-form-urlencoded" 格式编码的查询组件 ([RFC3986] 第 3.4 节), 在添加额外查询参数时必须保留该组件. 端点 URI 禁止包含片段组件.
由于发送到授权端点的请求会导致用户认证以及明文凭据的传输 (在 HTTP 响应中), 授权服务器在向授权端点发送请求时必须要求使用第 1.6 节所述的 TLS.
授权服务器必须支持在授权端点使用 HTTP "GET" 方法 [RFC2616], 也可以支持使用 "POST" 方法.
发送时没有值的参数必须视为从请求中省略. 授权服务器必须忽略无法识别的请求参数. 请求和响应参数禁止包含多次.
3.1.1. 响应类型
授权端点由授权码许可类型流程和隐式许可类型流程使用. 客户端使用以下参数告知授权服务器所需的许可类型:
response_type 必需. 值必须是 "code" 之一, 用于请求第 4.1.1 节所述的授权码; 或 "token", 用于请求第 4.2.1 节所述的访问令牌 (隐式许可); 或第 8.4 节所述的已注册扩展值.
扩展响应类型可以包含以空格 (%x20) 分隔的值列表, 其中值的顺序无关紧要 (例如响应类型 "a b" 与 "b a" 相同). 这种复合响应类型的含义由各自的规范定义.
如果授权请求缺少 "response_type" 参数, 或响应类型无法理解, 授权服务器必须按第 4.1.2.1 节所述返回错误响应.
3.1.2. 重定向端点
完成与资源所有者的交互后, 授权服务器会将资源所有者的用户代理定向回客户端. 授权服务器会把用户代理重定向到客户端的重定向端点, 该端点先前在客户端注册过程中或发起授权请求时已与授权服务器建立.
重定向端点 URI 必须是 [RFC3986] 第 4.3 节定义的绝对 URI. 端点 URI 可以包含按 Appendix B 规定的 "application/x-www-form-urlencoded" 格式编码的查询组件 ([RFC3986] 第 3.4 节), 在添加额外查询参数时必须保留该组件. 端点 URI 禁止包含片段组件.
3.1.2.1. 端点请求机密性
当所请求的响应类型是 "code" 或 "token", 或者重定向请求会导致敏感凭据通过开放网络传输时, 重定向端点应当要求使用第 1.6 节所述的 TLS. 本规范不强制使用 TLS, 因为在撰写本文时, 要求客户端部署 TLS 对许多客户端开发者来说是一个重大障碍. 如果 TLS 不可用, 授权服务器应当在重定向之前警告资源所有者该端点不安全 (例如在授权请求期间显示消息).
缺少传输层安全会对客户端以及其被授权访问的受保护资源的安全性产生严重影响. 当授权过程被客户端用作委托的最终用户认证形式 (例如第三方登录服务) 时, 使用传输层安全尤其关键.
3.1.2.2. 注册要求
授权服务器必须要求以下客户端注册其重定向端点:
o 公共客户端.
o 使用隐式许可类型的机密客户端.
授权服务器应当要求所有客户端在使用授权端点之前注册其重定向端点.
授权服务器应当要求客户端提供完整的重定向 URI (客户端可以使用 "state" 请求参数实现每个请求的定制). 如果无法要求注册完整的重定向 URI, 授权服务器应当要求注册 URI 的 scheme, authority 和 path (允许客户端在请求授权时仅动态改变重定向 URI 的查询组件).
授权服务器可以允许客户端注册多个重定向端点.
缺少重定向 URI 注册要求可能使攻击者能够将授权端点用作开放重定向器, 如第 10.15 节所述.
3.1.2.3. 动态配置
如果已注册多个重定向 URI, 或仅注册了重定向 URI 的一部分, 或未注册任何重定向 URI, 客户端必须在授权请求中使用 "redirect_uri" 请求参数包含一个重定向 URI.
当授权请求包含重定向 URI 时, 授权服务器必须根据 [RFC3986] 第 6 节定义, 将接收到的值与至少一个已注册的重定向 URI (或 URI 组件, 如果存在) 进行比较并匹配. 如果客户端注册中包含完整重定向 URI, 授权服务器必须使用 [RFC3986] 第 6.2.1 节定义的简单字符串比较来比较两个 URI.
3.1.2.4. 无效端点
如果授权请求由于缺少, 无效或不匹配的重定向 URI 而验证失败, 授权服务器应当告知资源所有者该错误, 并且禁止自动将用户代理重定向到无效的重定向 URI.
3.1.2.5. 端点内容
对客户端端点的重定向请求通常会产生一个 HTML 文档响应, 由用户代理处理. 如果 HTML 响应是重定向请求的直接结果, HTML 文档中包含的任何脚本都将执行, 并拥有对重定向 URI 及其所含凭据的完全访问权限.
客户端不应在重定向端点响应中包含任何第三方脚本 (例如第三方分析, 社交插件, 广告网络). 相反, 它应当从 URI 中提取凭据, 并再次将用户代理重定向到另一个端点, 且不暴露凭据 (无论是在 URI 中还是其他位置). 如果包含第三方脚本, 客户端必须确保自己的脚本 (用于从 URI 中提取并移除凭据) 最先执行.
3.2. 令牌端点
令牌端点由客户端用于通过提交授权许可或刷新令牌来获得访问令牌. 除隐式许可类型以外, 令牌端点用于每一种授权许可 (因为隐式许可会直接签发访问令牌).
客户端如何获得令牌端点位置不在本规范范围内, 但该位置通常会在服务文档中提供.
端点 URI 可以包含按 Appendix B 规定的 "application/x-www-form-urlencoded" 格式编码的查询组件 ([RFC3986] 第 3.4 节), 在添加额外查询参数时必须保留该组件. 端点 URI 禁止包含片段组件.
由于发送到令牌端点的请求会导致明文凭据的传输 (在 HTTP 请求和响应中), 授权服务器在向令牌端点发送请求时必须要求使用第 1.6 节所述的 TLS.
客户端在发起访问令牌请求时必须使用 HTTP "POST" 方法.
发送时没有值的参数必须视为从请求中省略. 授权服务器必须忽略无法识别的请求参数. 请求和响应参数禁止包含多次.
3.2.1. 客户端认证
机密客户端或其他已获发客户端凭据的客户端, 在向令牌端点发起请求时必须按第 2.3 节所述向授权服务器认证. 客户端认证用于:
o 强制刷新令牌和授权码与其签发目标客户端之间的绑定. 当授权码通过不安全信道传输到重定向端点, 或者重定向 URI 未完整注册时, 客户端认证尤为关键.
o 在客户端被攻破时通过禁用客户端或修改其凭据来恢复, 从而防止攻击者滥用被盗的刷新令牌. 修改一组客户端凭据明显快于撤销整组刷新令牌.
o 实施认证管理最佳实践, 这些实践要求定期轮换凭据. 轮换整组刷新令牌可能很困难, 而轮换一组客户端凭据则明显更容易.
客户端在向令牌端点发送请求时可以使用 "client_id" 请求参数来标识自身. 在发往令牌端点的 "authorization_code" "grant_type" 请求中, 未认证客户端必须发送其 "client_id", 以防止自己无意中接受原本发给另一个 "client_id" 客户端的代码. 这可以保护客户端免受认证代码替换攻击. (它不会为受保护资源提供额外安全性.)
3.3. 访问令牌作用域
授权端点和令牌端点允许客户端使用 "scope" 请求参数指定访问请求的作用域. 相应地, 授权服务器使用 "scope" 响应参数告知客户端所签发访问令牌的作用域.
scope 参数的值表示为以空格分隔, 区分大小写的字符串列表. 这些字符串由授权服务器定义. 如果值包含多个以空格分隔的字符串, 它们的顺序无关紧要, 且每个字符串都会向所请求的作用域添加一个额外访问范围.
scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
授权服务器可以根据授权服务器策略或资源所有者指示, 完全或部分忽略客户端请求的作用域. 如果签发的访问令牌作用域与客户端请求的作用域不同, 授权服务器必须包含 "scope" 响应参数, 以告知客户端实际授予的作用域.
如果客户端在请求授权时省略 scope 参数, 授权服务器必须使用预定义默认值处理请求, 或使请求失败并指出作用域无效. 授权服务器应当记录其作用域要求和默认值 (如果已定义).