从 Ansible Tower 3.3 开始,使用 OAuth 2 进行基于令牌的身份验证。您可以管理 OAuth 令牌以及应用,即用于生成令牌的 API 客户端的服务器端系统。通过将 OAuth 令牌作为 HTTP 验证标头的一部分,您可以自行验证身份,并调整除了基本 RBAC 权限外的限制性权限的程度。如需 OAuth 2 规格的详情,请参阅 RFC 6749。
如需有关使用 manage
实用程序创建令牌的详情,请参考 令牌和会话管理 部分。
应用和令牌可以作为 /api/<version>/applications
和 /api/<version>/tokens
的顶层资源进行管理。这些资源也可以由 /api/<version>/users/N/<resource>
的用户相应地访问。可以通过对 api/<version>/applications
或 /api/<version>/users/N/applications
发出 POST 来创建应用。
每个 OAuth 2 应用都代表了服务器端的一个特定的 API 客户端。对于 API 客户端,要通过应用令牌使用 API,它必须首先具有一个应用并签发了一个访问令牌。每个应用都可通过主键:/api/<version>/applications/<pk>/
访问。这里是一个典型的应用:
{
"id": 1,
"type": "o_auth2_application",
"url": "/api/v2/applications/2/",
"related": {
"tokens": "/api/v2/applications/2/tokens/"
},
"summary_fields": {
"organization": {
"id": 1,
"name": "Default",
"description": ""
},
"user_capabilities": {
"edit": true,
"delete": true
},
"tokens": {
"count": 0,
"results": []
}
},
"created": "2018-07-02T21:16:45.824400Z",
"modified": "2018-07-02T21:16:45.824514Z",
"name": "My Application",
"description": "",
"client_id": "Ecmc6RjjhKUOWJzDYEP8TZ35P3dvsKt0AKdIjgHV",
"client_secret": "7Ft7ym8MpE54yWGUNvxxg6KqGwPFsyhYn9QQfYHlgBxai74Qp1GE4zsvJduOfSFkTfWFnPzYpxqcRsy1KacD0HH0vOAQUDJDCidByMiUIH4YQKtGFM1zE1dACYbpN44E",
"client_type": "confidential",
"redirect_uris": "",
"authorization_grant_type": "password",
"skip_authorization": false,
"organization": 1
}
如上例所示,name
是应用的人类可读标识符。其它字段(如 client_id
和 redirect_uris
)主要用于 OAuth2 授权,它在后面的:ref:ag_use_oauth_pat 中介绍。
client_id
和 client_secret
字段的值在创建过程中生成 ,它们是应用的不可编辑标识符,而在创建时还需要 organization
和 authorization_grant_type
,并变为不可编辑。
应用的访问规则如下:
系统管理员可以查看并操作系统中的所有应用
机构管理员可以查看和操作属于机构成员的所有应用
其他用户只能查看、更新和删除自己的应用,但无法创建新应用
另一方面,令牌是用于实际身份验证传入请求和屏蔽底层用户权限的资源。令牌可以通过两个方法创建:
使用 application
和 scope
字段发布到 /api/v2/tokens/
端点,以指向相关应用并指定令牌范围
使用 scope
字段发布到 /api/v2/applications/<pk>/tokens/
端点(父应用会自动链接)
单独的令牌可以通过它们的主键:/api/<version>/tokens/<pk>/
访问。这里是一个典型令牌的示例:
{
"id": 4,
"type": "o_auth2_access_token",
"url": "/api/v2/tokens/4/",
"related": {
"user": "/api/v2/users/1/",
"application": "/api/v2/applications/1/",
"activity_stream": "/api/v2/tokens/4/activity_stream/"
},
"summary_fields": {
"application": {
"id": 1,
"name": "Default application for root",
"client_id": "mcU5J5uGQcEQMgAZyr5JUnM3BqBJpgbgL9fLOVch"
},
"user": {
"id": 1,
"username": "root",
"first_name": "",
"last_name": ""
}
},
"created": "2018-02-23T14:39:32.618932Z",
"modified": "2018-02-23T14:39:32.643626Z",
"description": "App Token Test",
"user": 1,
"token": "*************",
"refresh_token": "*************",
"application": 1,
"expires": "2018-02-24T00:39:32.618279Z",
"scope": "read"
},
对于 OAuth 2 令牌,唯一完全可编辑的字段是 scope
和 description
。application
字段在更新时不可编辑,且所有其他字段完全不可编辑,并在创建过程中自动填充,如下所示:
user
字段与为其创建令牌的用户对应,在本例中,也是创建令牌的用户
expires
根据 Tower 配置设置生成 OAUTH2_PROVIDER
token
和 refresh_token
是自动生成的、没有冲突的随机字符串
应用令牌和个人访问令牌都显示在 /api/v2/tokens/
端点中。个人访问令牌中的 application
字段始终为 null。这是区分两种令牌的好方法。
令牌的访问规则如下:
如果用户能够查看相关应用,则可以创建令牌;并且用户也可以为自己创建个人令牌。
系统管理员可以查看并操作系统中的每个令牌
机构管理员可以查看和操作属于机构成员的所有令牌
系统审核员(Auditor)可查看所有令牌和应用
其他普通用户只能查看和操作自己的令牌
注解
用户只能在创建时查看令牌或刷新令牌值。
获取 OAuth 2 令牌的最简单和最常见的方法是在 /api/v2/users/<userid>/personal_tokens/
端点上创建个人访问令牌,如下例所示:
curl -XPOST -k -H "Content-type: application/json" -d '{"description":"Personal Tower CLI token", "application":null, "scope":"write"}' https://<USERNAME>:<PASSWORD>@<TOWER_SERVER>/api/v2/users/<USER_ID>/personal_tokens/ | python -m json.tool
如果已安装,您还可以通过 jq
对 JSON 输出进行 pipe 操作。
以下是使用个人令牌访问使用 curl 的 API 端点的示例:
curl -k -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -X POST -d '{}' https://tower/api/v2/job_templates/5/launch/
在 Ansible Tower 中,OAuth 2 系统构建在 Django Oauth Toolkit 上,为授权、撤销和刷新令牌提供专用端点。这些端点可以在 /api/v2/users/<USER_ID>/personal_tokens/
端点下找到,它还提供了这些端点的一些用法的详细示例。这些特殊 OAuth 2 端点仅支持使用 x-www-form-urlencoded
Content-type,因此没有 api/o/*
端点接受 application/json
。
注解
您还可以通过为应用程序类型指定 null
,使用 /api/o/token
端点来请求令牌。
或者,您可以通过 Tower 用户界面为用户 add tokens,并配置访问令牌的过期时间及其关联的刷新令牌(如果适用)。
OAuth 2 令牌的范围是一个由空格分隔的、包括有效范围关键字(’read’ 和 ’write’)的字符串。这些关键字可以被配置,用来指定经过身份验证的 API 客户端的权限级别。通过使用 read 和 write 范围,可以在 Ansible Tower 的基于角色的访问控制 (RBAC) 权限系统上提供一个掩码层。”write” 范围为经过身份验证的用户提供了 RBAC 系统的完整权限,而“read”范围则仅为经过身份验证的用户提供读取权限。请注意,“write”包括了“read”的权限。
例如,如果您对作业模板有管理权限,则当通过会话或基本身份验证进行了身份验证后,可以查看、修改、启动和删除作业模板。相反,如果您使用 OAuth 2 令牌进行身份验证,而相关的令牌范围为“read”,您只能查看,但不能操作或启动作业模板,即使管理员也是如此。如果令牌范围是“write”或“read write”,则可以作为管理员充分利用作业模板。
要获取和使用令牌,首先请创建一个应用令牌:
创建一个应用,authorization_grant_type
设置为 password
。HTTP 将以下内容 POST 到 /api/v2/applications/
端点(提供您自己的机构 ID):
{
"name": "Admin Internal Application",
"description": "For use by secure services & clients. ",
"client_type": "confidential",
"redirect_uris": "",
"authorization_grant_type": "password",
"skip_authorization": false,
"organization": <organization-id>
}
创建一个端点并 POST 到 /api/v2/tokens/
:
{
"description": "My Access Token",
"application": <application-id>,
"scope": "write"
}
这会返回 <token-value>,可以用来为将来的请求进行身份验证(这不会再次显示)。
使用令牌访问资源。以下使用 curl 作为示例:
curl -H "Authorization: Bearer <token-value>" -H "Content-Type: application/json" -X GET https://<tower>/api/v2/users/
如果您还没有设置 CA 且正在使用 SSL,则可能需要 -k
标志。
要撤销令牌,您可以使用该令牌的 ID 在该令牌的详情页面上进行 DELETE。例如:
curl -ku <user>:<password> -X DELETE https://<tower>/api/v2/tokens/<pk>/
同样,使用令牌:
curl -H "Authorization: Bearer <token-value>" -X DELETE https://<tower>/api/v2/tokens/<pk>/ -k
本页列出了用于授权、令牌刷新和撤销的 OAuth 2 实用程序端点。/api/o/
端点不会在浏览器中使用,且不支持 HTTP GET。这里介绍的端点严格遵循 OAuth 2 的 RFC 规格,因此使用它进行详细参考。以下示例是 Tower 中这些端点的典型用法,特别是在使用各种授权类型创建应用时:
授权代码
密码
implicit
授权类型在 Ansible Tower 3.6 中被删除。
注解
您可以使用 Tower 用户界面执行此处所述的全部应用功能。如需更多详情,请参阅 Ansible Tower User Guide 的 Applications 部分。
authorization code
授权类型的应用¶当访问令牌需要签发到一个外部应用程序或服务时,应使用 authorization code
授权类型。
注解
当使用一个应用程序时,只能使用
authorization code
类型来获取访问令牌。如果一个外部 web 应用程序与 Ansible Tower 集成,那个 web 应用程序可能需要为该应用程序上的用户创建 OAuth2 令牌。实现这个目的的首选做法是在 Tower 中创建authorization code
授权类型的应用程序。这是因为:
外部应用程序可以为一个用户从 Tower 获取令牌作为用户的凭证
对为特定应用程序发布的令牌进行分离,可轻松管理这些令牌(例如,在不需要删除系统中*所有*令牌的情况下,删除与该应用程序关联的所有令牌)
要使用 authorization-code
授权类型创建名为 AuthCodeApp 的应用程序,请对 /api/v2/applications/
端点执行 POST:
{
"name": "AuthCodeApp",
"user": 1,
"client_type": "confidential",
"redirect_uris": "http://<tower>/api/v2",
"authorization_grant_type": "authorization-code",
"skip_authorization": false
}
.. _`Django-oauth-toolkit simple test application`: http://django-oauth-toolkit.herokuapp.com/consumer/
当使用 response_type
、client_id
、redirect_uris
和 scope
从客户端应用签发 GET 到 authorize
端点时发生的工作流:
Tower 使用授权代码和状态响应应用中指定的 redirect_uri
。
客户端应用然后使用 code
、client_id
、client_secret
、grant_type
和 redirect_uri
,向 Tower 上的 api/o/token/
端点发出 POST。
Tower 使用 access_token
、token_type
、refresh_token
和 expires_in
响应。
请参阅 Django's Test Your Authorization Server 工具包来测试这个流。
您可以在 Configure Tower - System 设置中指定授权代码保持有效的秒数:
此持续时间后请求访问令牌将会失败。根据 RFC6749 的建议,持续时间默认为 600 秒(10 分钟)。
使用授权代码授权类型设置应用与 Ansible Tower 集成的最佳方法是:将这些跨站点请求的起源列入白名单。更笼统地说,您需要将您要与 Tower 集成的服务或应用列入白名单,以便为其提供访问令牌。为此,您的管理员将这份白名单添加到其本地 Tower 设置中:
CORS_ORIGIN_REGEX_WHITELIST = [
r"http://django-oauth-toolkit.herokuapp.com*",
r"http://www.example.com*"
]
其中 http://django-oauth-toolkit.herokuapp.com
和 http://www.example.com
是需要令牌才能访问 Tower 的应用。
password
授权类型的应用¶password
或 Resource owner password-based
授权类型非常适合拥有对 web 应用的原生访问权限并在客户端为资源拥有者时使用的用户。以下是带有授权类型 password
的 'Default Application':
{
"id": 6,
"type": "application",
...
"name": "Default Application",
"user": 1,
"client_id": "gwSPoasWSdNkMDtBN3Hu2WYQpPWCO9SwUEsKK22l",
"client_secret": "fI6ZpfocHYBGfm1tP92r0yIgCyfRdDQt0Tos9L8a4fNsJjQQMwp9569eIaUBsaVDgt2eiwOGe0bg5m5vCSstClZmtdy359RVx2rQK5YlIWyPlrolpt2LEpVeKXWaiybo",
"client_type": "confidential",
"redirect_uris": "",
"authorization_grant_type": "password",
"skip_authorization": false
}
password
授权类型不需要登录,因此您可以简单地使用 curl 通过 /api/v2/tokens/
端点获取个人访问令牌:
curl -k --user <user>:<password> -H "Content-type: application/json" \
-X POST \
--data '{
"description": "Token for Nagios Monitoring app",
"application": 1,
"scope": "write"
}' \
https://<tower>/api/v2/tokens/
注解
特殊 OAuth 2 端点只支持使用 x-www-form-urlencoded
Content-type,因此,没有 api/o/*
端点接受 application/json
。
成功后,会以 JSON 格式显示一个响应,其中包含访问令牌、刷新令牌和其他信息:
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, 05 Dec 2017 16:48:09 GMT
Content-Type: application/json
Content-Length: 163
Connection: keep-alive
Content-Language: en
Vary: Accept-Language, Cookie
Pragma: no-cache
Cache-Control: no-store
Strict-Transport-Security: max-age=15768000
{"access_token": "9epHOqHhnXUcgYK8QanOmUQPSgX92g", "token_type": "Bearer", "expires_in": 315360000000, "refresh_token": "jMRX6QvzOTf046KHee3TU5mT3nyXsz", "scope": "read"}
本节介绍了与令牌关联的刷新和撤销功能。所有随后的功能(刷新和撤销 /api/o/
端点中的令牌)目前只能使用应用令牌完成。
以下示例显示了提供有刷新令牌的现有访问令牌:
{
"id": 35,
"type": "access_token",
...
"user": 1,
"token": "omMFLk7UKpB36WN2Qma9H3gbwEBSOc",
"refresh_token": "AL0NK9TTpv0qp54dGbC4VUZtsZ9r8z",
"application": 6,
"expires": "2017-12-06T03:46:17.087022Z",
"scope": "read write"
}
/api/o/token/
端点用于刷新访问令牌:
curl -X POST \
-d "grant_type=refresh_token&refresh_token=AL0NK9TTpv0qp54dGbC4VUZtsZ9r8z" \
-u "gwSPoasWSdNkMDtBN3Hu2WYQpPWCO9SwUEsKK22l:fI6ZpfocHYBGfm1tP92r0yIgCyfRdDQt0Tos9L8a4fNsJjQQMwp9569eIaUBsaVDgt2eiwOGe0bg5m5vCSstClZmtdy359RVx2rQK5YlIWyPlrolpt2LEpVeKXWaiybo" \
http://<tower>/api/o/token/ -i
在上述 POST 请求中,refresh_token
由上方的访问令牌的 refresh_token
字段提供。身份验证信息的格式是 <client_id>:<client_secret>
,其中 client_id
和 client_secret
是与访问令牌的底层相关应用的对应字段。
注解
特殊 OAuth 2 端点只支持使用 x-www-form-urlencoded
Content-type,因此,没有 api/o/*
端点接受 application/json
。
成功后,会以 JSON 格式显示一个响应,其中包含新的(刷新的)访问令牌,其范围信息与前面的信息相同:
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, 05 Dec 2017 17:54:06 GMT
Content-Type: application/json
Content-Length: 169
Connection: keep-alive
Content-Language: en
Vary: Accept-Language, Cookie
Pragma: no-cache
Cache-Control: no-store
Strict-Transport-Security: max-age=15768000
{"access_token": "NDInWxGJI4iZgqpsreujjbvzCfJqgR", "token_type": "Bearer", "expires_in": 315360000000, "refresh_token": "DqOrmz8bx3srlHkZNKmDpqA86bnQkT", "scope": "read write"}
本质上,刷新操作通过删除原始令牌替换现有的令牌,然后立即创建一个新的令牌,其范围和相关应用与原始令牌相同。验证是否存在新令牌,并在 /api/v2/tokens/
端点中删除旧令牌。
同样,您可以使用 /api/o/revoke-token/
端点来撤销访问令牌。
通过此方法撤销访问令牌与删除令牌资源对象相同,但它允许您通过提供令牌值以及关联的 client_id``(如果应用程序是 ``confidential
,则为 client_secret
)来删除令牌。例如:
curl -X POST -d "token=rQONsve372fQwuc2pn76k3IHDCYpi7" \
-u "gwSPoasWSdNkMDtBN3Hu2WYQpPWCO9SwUEsKK22l:fI6ZpfocHYBGfm1tP92r0yIgCyfRdDQt0Tos9L8a4fNsJjQQMwp9569eIaUBsaVDgt2eiwOGe0bg5m5vCSstClZmtdy359RVx2rQK5YlIWyPlrolpt2LEpVeKXWaiybo" \
http://<tower>/api/o/revoke_token/ -i
注解
特殊 OAuth 2 端点只支持使用 x-www-form-urlencoded
Content-type,因此,没有 api/o/*
端点接受 application/json
。
注解
**Allow External Users to Create Oauth2 Tokens**(API 中的 ALLOW_OAUTH2_FOR_EXTERNAL_USERS
)设置默认禁用。外部用户是指使用类似 LDAP 的服务或其它 SSO 服务进行外部身份验证的用户。此设置确保外部用户无法*创建*自己的令牌。如果启用了这个设置并在随后禁用它,则外部用户在此期间创建的令牌仍会存在,它们不会被自动撤销。
或者,您可以使用 manage
实用程序 revoke_oauth2_tokens 撤销令牌,如 令牌和会话管理 部分中所述。
此设置可以在 Ansible Tower 用户界面中的系统级别进行配置:
成功后,会显示一个响应 200 OK
。通过检查 /api/v2/tokens/
端点中是否存在令牌来验证删除。