OAuth for Data Plan Agent API

OAuth 2.0 已标准化为 RFC 6749。如需查看详细文档,请访问 https://oauth.net/2。HTTP 基本身份验证在 RFC 2617 的第 2 节中定义。

概览

通常,为了向第三方应用提供对受限资源(例如流量套餐和钱包详细信息)的访问权限,最终用户(资源所有者)需要与第三方共享其凭据。这会带来凭据存储、密码身份验证、对最终用户资源的广泛访问和密码泄露等诸多问题和限制。OAuth2.0 通过引入授权层来解决这些问题,从而保护和限制对最终用户受保护资源的访问。

GTAF 不会使用最终用户的凭据来访问受保护的资源(例如流量套餐详情),而是会获取访问令牌。访问令牌是代表 GTAF 的凭据向 GTAF 签发的。然后,GTAF 使用该访问令牌来访问 DPA 托管的流量套餐详细信息。

下图简要展示了信息流:

图 1:抽象 OAuth 流程。

访问令牌

访问令牌是 GTAF 用于从运营商的 DPA 访问流量套餐详情的凭据。访问令牌是一个字符串,表示向 GTAF 授予的授权。该字符串通常对 GTAF 不透明。令牌表示最终用户授予运营商的特定访问权限范围和时长,由 DPA 和运营商的 OAuth 服务器强制执行。

访问令牌提供了一个抽象层,用 DPA 可理解的单个令牌替换了不同的授权构造(例如,用户名和密码)。这种抽象化功能可让 DPA 发放比用于获取访问令牌的授权许可更具限制性的访问令牌,同时还可让 DPA 无需了解各种身份验证方法。

访问令牌可以具有不同的格式、结构和使用方法(例如,加密属性),具体取决于运营商的安全要求。GTAF 仅支持 [RFC6750] 中定义的令牌类型。

客户端身份验证

GTAF 可充当“保密客户端”,能够确保密码安全。目前,GTAF 仅支持 HTTP 基本身份验证,以便通过 DPA 进行身份验证。客户端标识符使用“application/x-www-form-urlencoded”编码算法进行编码,编码后的值用作用户名;密码使用相同的算法进行编码,并用作密码。

机密客户端(例如 GTAF)会获得客户端凭据,在向令牌端点发出请求时,会通过运营商的 OAuth 服务器进行身份验证。客户端身份验证用于:\

  • 通过停用客户端或更改其凭据来从遭入侵的客户端中恢复,从而防止攻击者滥用窃取的刷新令牌。更改一组客户端凭据比撤消整组刷新令牌快得多。
  • 实施身份验证管理最佳实践,这需要定期轮替凭据。

GTAF 在向令牌端点发送请求时,会使用“client_id”请求参数来标识自身。

尤其重要的是能够轮替客户端凭据。OAuth 服务器必须能够在轮换期间支持两对同时存在的凭据,并且必须能够停用凭据。在典型的凭据轮替中:

  1. 运营商在 OAuth 服务器上创建新凭据,并以安全的方式将凭据交付给其技术客户经理。
  2. Google 会测试新凭据,并更改 GTAF 配置以使用新凭据。
  3. Google 会通知运营商旧凭据可能已被停用。
  4. 运输公司停用凭据并通知 Google
  5. Google 验证旧凭据是否不再有效

OAuth 服务器必须能够支持上述轮换流程。

令牌端点

GTAF 通过提供其授权许可或刷新令牌来使用令牌端点获取访问令牌。令牌端点可用于除隐式授权类型之外的所有授权许可(因为访问令牌是直接颁发的)。

配置令牌端点时,请考虑以下几点:

  • 令牌端点的位置应在服务文档中提供。
  • 端点 URI 可能包含“application/x-www-form-urlencoded”格式的查询组件,添加其他查询参数时必须保留该组件。端点 URI 不得包含 fragment 组件。
  • 由于对令牌端点的请求会导致明文凭据(在 HTTP 请求和响应中)的传输,因此运营商的 OAuth 服务器必须使用 TLS 向令牌端点发送请求。
  • GTAF 在请求访问令牌时使用 HTTP“POST”方法。
  • 发送的参数若没有值,则必须视为从请求中省略。 OAuth 服务器必须忽略无法识别的请求参数。请求和响应参数不得包含多次。
  • GTAF 仅支持令牌类型的访问令牌。

访问令牌范围

授权和令牌端点允许客户端使用“scope”请求参数指定访问请求的范围。反过来,授权服务器会使用“scope”响应参数来告知客户端所签发的访问令牌的范围。

范围参数的值表示为以空格分隔且区分大小写的字符串列表。字符串由授权服务器定义。如果该值包含多个以空格分隔的字符串,则它们的顺序无关紧要,并且每个字符串都会为所请求的范围添加一个额外的访问范围。

 scope = scope-token *( SP scope-token )
 scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

GTAF 不要求实现该范围,但支持此功能。如需了解详情,请参阅 RFC 6749第 3.3 节

签发访问令牌

如果 GTAF 发送的访问令牌请求有效且已获得授权,OAuth 服务器会颁发访问令牌和可选的刷新令牌。如果请求未通过客户端身份验证或无效,OAuth 服务器会返回错误响应,如下一部分中所述。

成功响应

当 GTAF 发送请求时,OAuth 服务器会颁发访问令牌和可选的刷新令牌,并通过将以下参数添加到 HTTP 响应的实体正文中来构建响应,并返回 200 (OK) 状态代码: \

  • access_token::必需。由 OAuth 服务器颁发的访问令牌。 GTAF 希望令牌端点返回不记名令牌。
  • expires_in::必需。访问令牌的生命周期(以秒为单位)。例如,值“3600”表示访问令牌将在生成响应后一小时过期。如果省略,OAuth 服务器应通过其他方式提供过期时间,或记录默认值。
  • token_type::必需。所颁发的令牌的类型。如需详细了解不同类型的令牌,请参阅 RFC 6749 第 7.1 节。该值不区分大小写。在撰写本文时,GTAF 仅支持不记名令牌。
  • refresh_token::可选。刷新令牌,可用于使用相同的授权许可获取新的访问令牌。
  • 范围:如果已实现且与 GTAF 请求的范围相同,则为可选;否则为必需。

这些参数使用“application/json”包含在 HTTP 响应的实体正文中。通过在最高结构级别添加每个参数,将参数序列化为 JavaScript 对象表示法 (JSON) 结构。参数名称和字符串值以 JSON 字符串的形式包含在内。数值会作为 JSON 数字包含在内。参数的顺序无关紧要,可以随意调整。

授权服务器必须在包含令牌、凭据或其他敏感信息的任何响应中包含 HTTP“Cache-Control”响应标头字段(值为“no-store”),以及“Pragma”响应标头字段(值为“no-cache”)。

例如:

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"Bearer",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }


以下是一些需要考虑的重要事项:

  • GTAF 会忽略响应中无法识别的值名称。
  • 从 OAuth 服务器收到的令牌和其他值的大小未定义。
  • GTAF 应避免对值大小做出假设。OAuth 服务器应记录其颁发的任何值的大小。

错误响应

如果授权请求因任何原因(例如缺少、无效或不匹配的重定向 URI,或者缺少或无效的客户端标识符)而失败,OAuth 服务器应返回 HTTP 400(错误请求)状态代码(除非另有规定),并且应至少包含“错误响应和代码”部分中列出的一个参数。

GTAF 中的授权许可

授权许可是一种凭据,表示最终用户的授权(访问其受保护的资源,例如数据余额信息),GTAF 使用该凭据来获取访问令牌。

GTAF 使用 client_credentials 授权类型。在 client_credentials 授权类型中,GTAF 使用 HTTP POST 请求和 HTTP 基本身份验证来请求令牌。所有请求均通过 TLS 发送(即,HTTPS),并且 GTAF 无法与没有有效 TLS 证书的 OAuth 服务器集成。GTAF 能够传递可配置的令牌范围,如果未配置令牌范围,则会传递空范围。

GTAF 期望返回一个访问令牌以及一个“expires_in”值(有效时间)。expires_in 值应至少为 900 秒,且不应超过几个小时。请求新令牌不得导致现有令牌提前过期。

如需详细了解各种授权类型,请参阅 RFC 6749第 1.3 节

请求和响应示例

假设 GTAF 针对 OAuth 服务器具有以下配置:

URL: https://www.example.com/gettoken/
Client ID: gtaf
Client secret: password
Scope: dpa

注意:实际 DPA 的客户端密钥必须比示例中显示的密钥安全得多。

如需生成授权字符串,请将客户端 ID、':' 和密码串联起来,然后进行 base64 编码。您可以在命令行界面中按如下方式复制此操作:

$ echo -n gtaf:password | base64
Z3RhZjpwYXNzd29yZA==

然后,GTAF 使用这些凭据、client_credentials 授权类型和配置的范围向 OAuth 服务器发出 HTTPS POST 请求。对于此示例,GTAF 的请求类似于以下命令生成的请求:

$ curl -H 'Authorization: Basic Z3RhZjpwYXNzd29yZA==' -X POST \
-d 'grant_type=client_credentials&scope=dpa' 'https://www.example.com/gettoken/'

GTAF 使用的标头与 curl 发送的标头不匹配,但授权标头是相同的。

GTAF 期望的响应格式如下:

{
"access_token":"<token>",
"token_type": "Bearer",
"expires_in":<expiration time>
}

以下是有效回答的示例:

{
"access_token":"YXRudWhhZXVoLGFodWFoaGF1aG9zaHVvYWV1Cg",
"token_type": "Bearer",
"expires_in":3600
}

注意:响应必须是有效的 JSON。

错误响应和代码

如果来自 GTAF 的授权请求因“错误响应”部分中列出的任何原因而失败,OAuth 服务器必须以 HTTP 400(错误请求)状态代码(除非另有规定)进行响应,并在响应中包含以下参数之一:

例如:\

     HTTP/1.1 400 Bad Request
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "error":"invalid_request"
     }

GTAF 要求 OAuth 服务器支持以下错误响应

错误代码 回答 原因
HTTP 400 invalid_request 请求缺少必需参数、包含不受支持的参数值(授权类型除外)、重复包含某个参数、包含多个凭据、使用多个机制通过 GTAF 进行身份验证,或者存在其他格式错误。
HTTP 401 invalid_client 客户端身份验证失败(例如,客户端未知、未包含客户端身份验证或身份验证方法不受支持)。OAuth 服务器可能会返回 HTTP 401(未经授权)状态代码,以指明支持哪些 HTTP 身份验证方案。如果客户端尝试通过“Authorization”请求标头字段进行身份验证,OAuth 服务器必须以 HTTP 401(未经授权)状态代码进行响应,并包含与客户端使用的身份验证方案相匹配的“WWW-Authenticate”响应标头字段。
HTTP 500 OAuth 服务器故障

如需详细了解可用于调试的其他响应,请参阅 RFC 6749 第 5.2 节