19. 基于令牌的身份验证
OAuth 2 用于基于令牌的身份验证。您可以管理 OAuth 令牌以及应用程序,应用程序是用于生成令牌的 API 客户端的服务器端表示。通过在 HTTP 身份验证标头中包含 OAuth 令牌,您可以验证自己的身份并调整限制性权限的程度,此外还有基本 RBAC 权限。有关 OAuth 2 规范的更多详细信息,请参阅 RFC 6749。
有关使用 manage
实用程序创建令牌的详细信息,请参阅 令牌和会话管理 部分。
19.1. 管理 OAuth 2 应用程序和令牌
应用程序和令牌可以在 /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 授权,这将在后面的 使用 OAuth 2 令牌系统进行个人访问令牌 (PAT) 中介绍。
client_id
和 client_secret
字段的值在创建过程中生成,并且是不可编辑的应用程序标识符,而 organization
和 authorization_grant_type
在创建时是必需的,并且变为不可编辑的。
19.1.1. 应用程序访问规则
应用程序访问规则如下
系统管理员可以查看和操作系统中的所有应用程序
组织管理员可以查看和操作属于组织成员的所有应用程序
其他用户只能查看、更新和删除他们自己的应用程序,但不能创建任何新的应用程序
另一方面,令牌是用于实际验证传入请求并掩盖底层用户权限的资源。有两种方法可以创建令牌
使用
application
和scope
字段对/api/v2/tokens/
端点进行 POST 操作,以指向相关应用程序并指定令牌范围使用
scope
字段对/api/v2/applications/<pk>/tokens/
端点进行 POST 操作(父应用程序将自动链接)
可以通过主鍵访问各个令牌:/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
是根据 AWX 配置设置OAUTH2_PROVIDER
生成的token
和refresh_token
是自动生成的,以确保不冲突的随机字符串
应用程序令牌和个人访问令牌都显示在 /api/v2/tokens/
端点中。个人访问令牌中的 application
字段始终为 null。这是区分两种令牌类型的好方法。
19.1.2. 令牌访问规则
令牌访问规则如下
如果用户能够查看相关应用程序,则用户可以创建令牌;并且还可以为自己创建个人令牌
系统管理员能够查看和操作系统中的每个令牌
组织管理员能够查看和操作属于组织成员的所有令牌
系统审计员可以查看所有令牌和应用程序
其他普通用户只能查看和操作他们自己的令牌
注意
用户只能在创建时查看令牌或刷新令牌值。
19.2. 使用 OAuth 2 令牌系统进行个人访问令牌 (PAT)
获取 OAuth 2 令牌最简单、最常用的方法是在 /api/v2/users/<userid>/personal_tokens/
端点创建个人访问令牌,如以下示例所示
curl -H "Content-type: application/json" -d '{"description":"Personal AWX CLI token", "application":null, "scope":"write"}' https://<USERNAME>:<PASSWORD>@<AWX_SERVER>/api/v2/users/<USER_ID>/personal_tokens/ | python -m json.tool
如果已安装,您也可以通过 jq
传递 JSON 输出。
以下是使用个人令牌访问 API 端点(使用 curl)的示例
curl -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{}' https://awx/api/v2/job_templates/5/launch/
在 AWX 中,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
端点请求令牌。
或者,您可以通过 AWX 用户界面 添加令牌,以及配置访问令牌及其关联的刷新令牌(如果适用)的过期时间。
19.2.1. 令牌范围掩码在 RBAC 系统之上
OAuth 2 令牌的范围是由有效范围关键字“read”和“write”组成的空格分隔字符串。这些关键字是可配置的,用于指定经过身份验证的 API 客户端的权限级别。读写范围在 AWX 的基于角色的访问控制 (RBAC) 权限系统之上提供了一个掩码层。具体来说,“write”范围赋予经过身份验证的用户 RBAC 系统提供的全部权限,而“read”范围仅赋予经过身份验证的用户 RBAC 系统提供的只读权限。请注意,“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" https://<awx>/api/v2/users/
如果您尚未设置 CA 并使用 SSL,则可能需要 -k
标志。
要撤销令牌,您可以对该令牌的详细信息页面执行 DELETE 操作, 使用该令牌的 ID。例如:
curl -u <user>:<password> -X DELETE https://<awx>/api/v2/tokens/<pk>/
同样,使用令牌:
curl -H "Authorization: Bearer <token-value>" -X DELETE https://<awx>/api/v2/tokens/<pk>/
19.3. 应用程序功能
此页面列出了用于授权、令牌刷新和撤销的 OAuth 2 工具 端点。 /api/o/
端点不适用于浏览器,并且不支持 HTTP GET。 此处规定的端点严格遵循 OAuth 2 的 RFC 规范,因此请使用它作为详 细参考。以下是 AWX 中这些端点的典型使用示例,尤其是创建 使用各种授权类型的应用程序时。
授权码
密码
注意
您可以使用 AWX 用户界面执行此处描述的任何应用程序功 能。有关详细信息,请参阅 *AWX 用户指南* 中的 应用程序 部分。
19.3.2. 使用 password
授权类型的应用程序
password
授权类型或 Resource owner password-based
授权类型非常适合对 web 应用程序具有本机访问权限的用户, 并且应在客户端为资源所有者时使用。以下假设一个名为“默认 应用程序”的应用程序,其授权类型为 password
。
{
"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 --user <user>:<password> -H "Content-type: application/json" \ --data '{ "description": "Token for Nagios Monitoring app", "application": 1, "scope": "write" }' \ https://<awx>/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"}
19.4. 应用程序令牌功能
本节描述与令牌相关的刷新和撤销功能。以下所有内容(在 /api/o/
端点刷新和撤销令牌)当前只能使用应用程序令牌完成。
19.4.1. 刷新现有的访问令牌
以下示例显示了具有提供刷新令牌的现有访问令牌。
{
"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 \
-d "grant_type=refresh_token&refresh_token=AL0NK9TTpv0qp54dGbC4VUZtsZ9r8z" \
-u "gwSPoasWSdNkMDtBN3Hu2WYQpPWCO9SwUEsKK22l:fI6ZpfocHYBGfm1tP92r0yIgCyfRdDQt0Tos9L8a4fNsJjQQMwp9569eIaUBsaVDgt2eiwOGe0bg5m5vCSstClZmtdy359RVx2rQK5YlIWyPlrolpt2LEpVeKXWaiybo" \
http://<awx>/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/
端点中删除。
19.4.2. 撤销访问令牌
同样,您可以使用 /api/o/revoke-token/
端点撤销访问令牌。
通过这种方法撤销访问令牌与删除令牌资源对象相同,但它允许您 通过提供其令牌值和关联的 client_id
(以及如果应用程序为 confidential
,则提供 client_secret
)来删除令牌。例如:
curl -d "token=rQONsve372fQwuc2pn76k3IHDCYpi7" \
-u "gwSPoasWSdNkMDtBN3Hu2WYQpPWCO9SwUEsKK22l:fI6ZpfocHYBGfm1tP92r0yIgCyfRdDQt0Tos9L8a4fNsJjQQMwp9569eIaUBsaVDgt2eiwOGe0bg5m5vCSstClZmtdy359RVx2rQK5YlIWyPlrolpt2LEpVeKXWaiybo" \
http://<awx>/api/o/revoke_token/ -i
注意
特殊的 OAuth 2 端点仅支持使用 x-www-form-urlencoded
**Content-type**,因此, api/o/*
端点都不接受 application/json
。
注意
默认情况下,**允许外部用户创建 OAuth2 令牌**(API 中的 ALLOW_OAUTH2_FOR_EXTERNAL_USERS
)设置处于禁用状态。外部用户是指 使用诸如 LDAP 之类的服务或任何其他 SSO 服务在外部进行身份验证 的用户。此设置确保外部用户无法 *创建* 自己的令牌。如果您启用它, 然后禁用它,在此期间由外部用户创建的任何令牌仍然存在,并且不 会自动撤销。
或者,您可以使用 manage
实用程序 revoke_oauth2_tokens 来撤销令牌,如 令牌和会话管理 部分所述。
可以在 AWX 用户界面中的系统级别配置此设置。
成功后,将显示 200 OK
的响应。通过检查令牌是否存在于 /api/v2/tokens/
端点中来验证删除。