OAuth2.0 客户端凭证授权流程支持¶
提供一种能力,允许用户通过 RFC6749 OAuth 2.0 授权框架 中的客户端凭证授权方式将角色委派给第三方客户端 [1]。需要 Identity API 的 v3.0+ 版本。OAuth 派生的令牌允许第三方客户端访问用户创建的受保护资源。
问题描述¶
在当前的 Keystone 实现中,OAuth2.0 尚不支持。
然而,OpenStack Tacker,它提供 NFV 编排 API,需要 OAuth2.0 支持以满足一个众所周知的 NFV 标准,即 ETSI NFV。在 ETSI NFV 的 API 规范 [3] 中,仅允许 OAuth2.0 客户端凭证授权流程用于 API 客户端授权。为了满足此要求,我们需要 OpenStack 具备 OAuth2.0 授权服务器功能。
提议的变更¶
提出的变更允许用户选择性地使用 OAuth2.0 客户端凭证授权流程来授权 API 客户端。为了实现这一点,我们将 OAuth2.0 授权服务器作为 Keystone 的扩展来实现。
此服务器支持涉及访问令牌管理的以下 API。
访问令牌 API
创建访问令牌
警告
请注意,根据 RFC6749 [1],由于某些请求以明文形式包含敏感信息,例如客户端密钥,因此授权服务器必须启用 HTTPS。
警告
请注意,本文档中描述的 OAuth 2.0 API 使用应用程序凭证 [5] 作为其后端。因此,OAuth2.0 用户必须被分配适当的角色才能访问所有应用程序凭证 API
术语¶
用户: 使用 Identity API 服务的最终用户,其角色将被委派的实体,以及注册客户端的实体。
客户端: 代表用户发出受保护资源请求的应用程序。客户端的凭证是通过应用程序凭证 API [5] 创建的。
访问令牌: 客户端用于使用委派的角色发出受保护资源请求的令牌。
OAuth2.0 客户端凭证授权流程¶
该流程包含以下步骤,如上图所示。
Identity API 服务用户创建一个应用程序凭证。
客户端在 Keystone 上与授权服务器进行身份验证,并请求一个新的访问令牌。
客户端使用访问令牌发出 OpenStack 服务 API 请求。
Keystone 中间件验证 API 请求中的访问令牌以获取其元数据和有效性,如果令牌有效,则将请求转发到 OpenStack 服务。
API 资源¶
访问令牌 API¶
创建访问令牌¶
POST /identity/v3/OS-OAUTH2/token
请求
Host: server.example.com
Authorization: Basic NzkxZDVlZDI2MjAxNDE4NWI4NTRlZjJhZGUwZGM0NWE6SkRKaUpEQTBKRXhpVnpBM2JtMUVaazVRTUhOWlpuSmxZMUJXZVM1UE1qY3dNR3hZZFROc1JtbG1jVE5wY1Vka2NtNVdkVkZ6TlhwNGFHVlQ=
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
响应
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "gAAAAABhi1cMynG89h8t6TJrxNiZuNzjcIUIxNctoVfuqTw7BpUedLKxjPymClVEnj9GhIT5u2mpjaJATlEAtaa3D6_t8jk_fV-mqo2IUlsmTPTnMwkcjh5FSHQVRdqvDxgY3nSqLA_Hfv-zPmjS5KWX3hmyDE5YWO1ztX6QNVQb4wTPyNL1-7I",
"token_type": "Bearer",
"expires_in": 3600
}
错误响应
HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Keystone uri="http://keysone.identity.host/identity/v3/auth/clients"
Cache-Control: no-store
Pragma: no-cache
{"error": “invalid_client", “error_description": “The client_id is not found or client_secret is invalid."]}
客户端使用其凭证请求访问令牌。如果凭证有效,Identity 服务将颁发一个新的访问令牌。否则,返回错误响应。响应中的 Authorization 字段,带有 Basic 字段,包含应用程序凭证 ID 和密码用单个冒号连接的 Base64 编码。
Keystone 中间件通过 Identity API /identity/v3/auth/tokens 获取访问令牌的元数据。
请注意,根据 RFC6749 [1],RFC6750 [2] 中定义的“bearer”令牌类型用于在 API 请求中包含访问令牌字符串。Keystone 中间件必须从带有 Authorization 标头的请求中获取访问令牌。
GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer gAAAAABhi1cMynG89h8t6TJrxNiZuNzjcIUIxNctoVfuqTw7BpUedLKxjPymClVEnj9GhIT5u2mpjaJATlEAtaa3D6_t8jk_fV-mqo2IUlsmTPTnMwkcjh5FSHQVRdqvDxgY3nSqLA_Hfv-zPmjS5KWX3hmyDE5YWO1ztX6QNVQb4wTPyNL1-7I
如果令牌有效,Keystone 中间件仅使用元数据更新请求标头。如果令牌无效或返回错误响应,则它会拒绝请求并返回 401 Unauthorized。Keystone 中间件使用“身份验证和令牌管理 API” [4] 来验证和获取令牌元数据。
备选方案¶
无
安全影响¶
在客户端凭证授权流程期间,一些敏感值以明文形式发送。因此,使用此功能的 Keystone 必须启用 HTTPS。
此代码将管理 Keystone 和第三方应用程序之间的协商。但是,此功能的后端是应用程序凭证,该凭证已在 Keystone 中实现。我们将仅实现在此功能之上的逻辑。
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
Keystone 中间件配置¶
要使用 OAuth2.0 访问令牌,部署者必须通过更改 [filter:authtoken] 在 /etc/tacker/api-paste.ini 中配置 Keystone 中间件,如下所示。如果 paste.filter_factory 是 keystonemiddleware.oauth2_token:filter_factory,则 Keystone 中间件期望在 Authorization 标头中找到令牌,而如果 paste.filter_factory 是 keystonemiddleware.oauth2_token:filter_factory,则 Keystone 中间件期望在 X-Auth-Token 标头中找到令牌。
[filter:authtoken]
paste.filter_factory = keystonemiddleware.oauth2_token:filter_factory
开发人员影响¶
无
实现¶
负责人¶
- 主要负责人
Hiromu Asahina (h-asahina) <hiromu.asahina.az@hco.ntt.co.jp>
- 其他贡献者
Yusuke Niimi <niimi.yusuke@fujitsu.com>
Keiichiro Yamakawa <yamakawa.keiich@fujitsu.com>
工作项¶
为 OAuth2.0 客户端凭证授权流程向 Keystone 添加新的 REST API 端点。
对 keystonauth 进行更改以支持使用 OAuth2.0 访问令牌进行授权。
为新的端点添加单元测试。
向 Keystone 中间件添加新的 AuthProtocol 来处理“bearer”令牌类型。
为新的 AuthProtocol 添加单元测试。
更改 API Keystone 文档。
更改 API Keystone 中间件文档。
依赖项¶
无
文档影响¶
我们需要更新用户 API 文档和身份验证机制。
我们需要更新用户 API 文档和中间件架构。