Plone的令牌认证
项目描述
ftw.tokenauth
PAS插件,通过实现使用服务密钥和短寿命访问令牌的双端OAuth2流程,简化了机器之间的认证。
安装
将ftw.tokenauth添加到您的buildout配置或作为策略包的依赖项。
[instance]
eggs +=
ftw.tokenauth
安装ftw.tokenauth的通用设置配置文件。
配置
要允许用户发布(或以其他方式管理)服务密钥,他们需要ftw.tokenauth: Manage own Service Keys权限。因此,集成包需要将此权限分配给应允许使用服务密钥的角色。
认证流程
认证流程包括四个步骤
登录的服务用户在Plone中发布服务密钥,并将私钥存储在客户端应用程序可安全访问的位置。
客户端应用程序使用私钥创建并签名JWT授权授予。
客户端应用程序将JWT授权授予与@@oauth2-token端点的短寿命访问令牌进行交换。
客户端随后使用此访问令牌来验证对受保护资源的请求。
假设客户端拥有服务密钥,则流程如下
基本用法
为了为客户端设置机器之间的认证,需要执行以下步骤
1. 发布服务密钥
已通过常规方式认证到Plone并具有ftw.tokenauth: Manage own Service Keys权限的用户,可以通过@@manage-service-keys视图(个人工具菜单中的“管理服务密钥”操作)为其账户发布服务密钥。
他们需要发布一个服务密钥,该密钥将恰好一次显示以供下载,并将私钥存储在客户端可安全访问的位置。
在发布密钥时,还可以定义IP范围限制。
待办事项:记录密钥撤销。
3. 令牌请求(交换JWT授予以获取访问令牌)
客户端随后使用其创建的JWT授予向token_uri发出令牌请求。
此请求必须是POST请求,Content-Type: application/x-www-form-urlencoded,并且请求体包含表单编码的参数。
需要两个参数
名称 |
描述 |
---|---|
grant_type |
必须始终是urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion |
JWT授权授予 |
令牌端点随后将响应一个包含访问令牌的令牌响应
{
"access_token": "<token>",
"expires_in": 3600,
"token_type": "Bearer"
}
响应将为 Content-Type: application/json,并包含一个JSON编码的正文。
Python示例
import requests
GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
payload = {'grant_type': GRANT_TYPE, 'assertion': grant}
response = requests.post(service_key['token_uri'], data=payload)
token = response.json()['access_token']
待办:记录令牌请求的错误响应
4. 使用访问令牌进行身份验证
客户端可以使用访问令牌进行身份验证。令牌需要以HTTP Authorization头中的Bearer令牌的形式发送。
一旦令牌过期,客户端必须再次创建JWT授权授予,并请求新的访问令牌。
Python示例
with requests.Session() as session:
session.headers.update({'Authorization': 'Bearer %s' % token})
response = session.get('https://127.0.0.1:8080/Plone/')
# ...
如果客户端使用的令牌已过期,服务器将响应错误响应
{
"error": "invalid_token",
"error_description": "Access token expired"
}
然后客户端应签署另一个JWT身份验证授予,请求新的令牌,并使用原始参数以及新的令牌重新发送失败的请求。
推荐客户端实现
在客户端实现重复身份验证和获取新访问令牌的推荐逻辑如下所示
客户端应,而不是尝试预测访问令牌的过期时间,只需预计使用现有令牌进行身份验证将会失败(因为令牌已过期),然后执行必要的步骤以获取新的令牌。
为此,建议将客户端应用程序想要进行的所有请求委托给一个期望上述访问令牌已过期响应的类,并在必要时获取新的令牌。导致错误响应的失败请求需要使用其原始参数重新发送,但然后在Authorization头中使用新的令牌。
在获取新令牌时,需要特别注意不要将过期的令牌(或任何Authorization头)包含在发送到令牌端点的请求中。
Python中的示例实现可以在docs/client-example.py中找到。
高级用法
本节涵盖了一些关于ftw.tokenauth的高级设置和功能。
IP范围限制
在颁发密钥时,可以定义IP范围限制,限制与该密钥关联的访问令牌可以使用的源IP地址。
给定密钥的IP范围限制的更改立即生效,并影响已颁发给此密钥的令牌。
IP范围可以指定为单个IP地址或使用斜杠后缀的CIDR表示法。
可以以逗号分隔的形式提供多个范围。
有效IP范围指定的示例
192.168.1.1
192.168.0.0/16
192.168.1.1, 10.0.0.0/8
来自未经授权的源IP地址的认证尝试将在服务器端进行记录,但不会以任何特定方式通知客户端 - 认证只是没有执行。
伪装
伪装允许以任意用户身份进行身份验证,而不是颁发服务密钥的用户。如果例如应用程序需要在不同用户上下文中执行操作,则这很有用。
要能够伪装成另一个用户,服务密钥用户需要具有ftw.tokenauth: Impersonate user权限。默认情况下,此权限仅授予Manager角色。请注意,使用此权限,用户可以伪装成具有更高权限的用户,因此实际上获得了系统中最有权限用户的全部权限。
要伪装成用户,在请求访问令牌时,请传递其用户ID或登录名,而不是服务密钥用户的用户ID,并在JWT令牌中使用sub声明。
使用日志
在“管理服务密钥”视图中,“Last Used”列列出了密钥最后一次用于颁发访问令牌的时间。点击此时间戳将显示密钥最近使用情况的详细日志。
默认情况下,这些日志列出了密钥在过去7天内的使用情况(使用日志保留期可以通过ZMI上的PAS插件属性进行配置)。
密钥最近一次使用记录始终保留,而其他日志条目如果已过期则会被清理(清理发生在每次颁发新访问令牌时)。
日志不显示访问令牌的认证使用情况,而是显示使用此密钥签名的JWT认证实例用于获取新访问令牌的每个实例。
链接
版权
本软件包的版权归4teamwork所有。
ftw.tokenauth遵循GNU通用公共许可证,版本2。
变更日志
1.2.0 (2023-12-13)
添加根据用户名(登录)查找备选用户的实现。[phgross]
1.1.0 (2018-07-12)
允许模拟其他用户。[buchi]
1.0.1 (2018-04-16)
将IP范围解析从py2-ipaddress模块切换到ipaddress模块,并修复了Unicode处理问题。[lgraf]
1.0.0 (2018-04-04)
初始实现 [lgraf]
项目详情
ftw.tokenauth-1.2.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | fa87a686faed994a332d1d92722b042132a647a674630e6f90d73209d813a427 |
|
MD5 | eea73d871d5da0bfb1cd07b98abb4d94 |
|
BLAKE2b-256 | 9390b0cc87bf82dd11cf3cb6d01696153e29e2c533b101c1d8c5eff0f350daca |