授权
July 1, 2024About 5 min
授权
云眼代理支持基于OAuth 和智威汤逊 标准,允许保护对其 API 和管理界面的访问。
有三种操作模式:
- 发行人和验证人
- 仅限验证人
- 代理验证在其他位置颁发的访问令牌。访问令牌使用从配置中提供的 JWKS URL 获取的公钥进行验证。
- 如果要直接插入系统或组织中已在使用的基于 JWT 的现有工作流,则仅验证器模式非常有用。
- 无授权(默认)
- 该接口是公开可用的。
配置
- API 和管理界面各自独立配置为在上述操作模式之一中运行。
- 授权配置位于
auth
密钥下 - 每种操作模式都有自己的一组配置属性,如下所述。
1. 发行人和验证人
下面列出了与颁发者和验证器模式相关的配置属性:
属性名称 | 环境变量 | 描述 |
---|---|---|
ttl | TTL | 已颁发的访问令牌的生存时间 |
hmacSecrets | HMACSECRETS | 用于使用 HMAC SHA256 算法对访问令牌进行签名和验证的机密数组。值必须是 base64 格式的字符串。数组中的第一个值用于对颁发的访问令牌进行签名。使用数组中的任何值签名的访问令牌被视为有效 |
客户 | 不适用 | 用于令牌颁发的对象数组,由id 、secretHash 和sdkKeys 组成。客户端在向/oauth/token 的请求中提供 ID 和机密。代理通过检查 ID 的完全匹配、检查请求机密的 BCrypt 哈希是否与secretHash 配置匹配以及X-eyeofcloud-Sdk-Key 请求标头中提供的 SDK 密钥是否存在于sdkKeys 发件人配置中来验证请求凭据。 secretHash 值必须是 base64 格式的字符串。 |
为了简化设置,Agent 提供了一个命令行工具,该工具可以生成 base64 编码的 32 字节随机值及其关联的 base64 编码的 BCrypt 哈希:
Shell
// From the Agent root directory
> make generate_secret
Client Secret: i3SrdrCy/wEGqggv9OI4FgIsdHHNpOacrmIMJ6SFIkE=
Client Secret's hash: JDJhJDEyJERGNzhjRXVTNTdOQUZ3cndxTkZ6Li5XQURlazU2R21YeFZjb1pWSkN5eGZ1SXM4VXRLb0ZD
使用哈希值配置代理,并在向client_secret
发出访问令牌请求时将密钥值传递给/oauth/token
。有关访问令牌颁发端点的详细信息,请参阅 OpenAPI 规范文件。
2. 仅限验证人
下面列出了与仅验证程序模式相关的配置属性:
属性名称 | 环境变量 | 描述 |
---|---|---|
jwksURL | JWKSURL | 应从中获取公钥以进行令牌验证的 URL |
jwksUpdateInterval | JWKSUPDATEINTERVAL | 应重新获取公钥的时间间隔(例如:30m 30 分钟) |
3. 无授权(默认)
未提供auth
配置时,API 和管理界面无需授权即可运行。
配置示例
云眼代理使用 Viper 库进行配置,该库允许通过环境变量、标帜和 YAML 配置文件设置值。
1. 发行人和验证人
❗
️警告
为了安全起见,我们建议使用环境变量或标帜进行配置
hmacSecrets
,而不是通过配置文件进行配置。
在下面的示例中,管理界面在颁发者和验证器模式下配置,通过环境变量提供hmacSecrets
,其他值通过 YAML 配置文件提供。
Shell
// Comma-separated value, to set multiple hmacSecrets.
// Access tokens are signed with the first value.
// Access tokens are valid when they are signed with either of these values.
export EYEOFCLOUD_ADMIN_HMACSECRETS=QPtUGP/RqaXRltZf1QE1KxlF2Iuo09J0buZ3UNKeIr0,bkZAqSsZuM5NSnwEyO9Pzb6F8gGNu1BBuX/SpPaMeyM
YAML
admin:
auth:
# Access tokens will expire after 30 minutes
ttl: 30m
clients:
# Either of these two id/secret pairs can be exchanged for access tokens
- id: agentConsumer1
secretHash: XgZTeTvWaZ6fLiey6EBSOxJ2QFdd6dIiUcZGDIIJ+IY
sdkKeys:
# These credentials can be exchanged for tokens granting access to these two SDK keys
- abcd1234
- efgh5678
- id: agentConsumer2
secretHash: ssz0EEViKIinkFXxzqncKxz+6VygEc2d2rKf+la5rXM
sdkKeys:
# These credentials can be exchanged for tokens granting access only to this one SDK key
- ijkl9012
2. 仅限验证人
YAML
# In this example, the API interface is configured in Validator-only mode
api:
auth:
# Signing keys will be fetched from this url and used when validating access tokens
jwksURL: https://YOUR_DOMAIN/.well-known/jwks.json
# Siging keys will be periodically fetched on this interval
jwksUpdateInterval: 30m
密钥轮换(颁发者和验证者模式)
若要支持机密轮换,hmacSecrets
和clients
同时支持设置多个值。在hmacSecrets
中,第一个值将用于对颁发的令牌进行签名,但使用任何值签名的令牌将被视为有效。
示例 - Python
例
#!/usr/bin/python
import json
import requests
import sys
# This example demonstrates interacting with Agent running in Issuer & Validator mode.
# We obtain an access token and use it to request the current Eyeofcloud Config
# from the API interface.
# Fist, we need a secret value to sign access tokens.
# You can use the generate_secret tool included with Agent to generate this:
# > make generate_secret
# Client Secret: CvzvkWm3V1D9RBxPWEjC+ud9zvwcOvnnLkWaIkzDGyA=
# You can ignore the second line that says "Client Secret's hash".
# Then, set an environment variable to make this secret available to Agent:
# > export EYEOFCLOUD_API_AUTH_HMACSECRETS=CvzvkWm3V1D9RBxPWEjC+ud9zvwcOvnnLkWaIkzDGyA=
# Next, we need client credentials (ID & secret), and the BCrypt hash of our secret
# Again, you can use the generate_secret tool included with Agent to generate these:
#
# > make generate_secret
# Client Secret: 0bfLVX9U3Lpr6Qe4X3DSSIWNqEkEQ4bkX1WZ5Km6spM=
# Client Secret's hash: JDJhJDEyJEdkSHpicHpRODBqOC9FQzRneGIyNXU0ZFVPMFNKcUhkdTRUQXRzWUJOdjRzRmcuVGdFUTUu
#
# Take the hash, and add it to your agent configuration file (default: config.yaml) under the "api" section,
# along with your desired client ID and SDK key:
#
# auth:
# ttl: 30m
# clients:
# - id: clientid1
# secretHash: JDJhJDEyJEdkSHpicHpRODBqOC9FQzRneGIyNXU0ZFVPMFNKcUhkdTRUQXRzWUJOdjRzRmcuVGdFUTUu
# sdkKeys:
# - <Your SDK Key>
#
# Start Agent with the API interface running on the default port (8080).
# Then, finally, run the example, passing your SDK key, client ID and secret:
# > python auth.py <Your SDK Key> clientid1 0bfLVX9U3Lpr6Qe4X3DSSIWNqEkEQ4bkX1WZ5Km6spM=
#
# For more information, see docs/auth.md
if len(sys.argv) < 4:
sys.exit('Requires three arguments: <SDK-Key> <Client ID> <Client Secret>')
sdk_key = sys.argv[1]
client_id = sys.argv[2]
client_secret = sys.argv[3]
s = requests.Session()
s.headers.update({'X-Eyeofcloud-SDK-Key': sdk_key})
resp = s.get('http://localhost:8080/v1/config')
print('first config request, not including access token: response status = {}'.format(resp.status_code))
resp = s.post('http://localhost:8080/oauth/token', data={
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
})
resp_dict = resp.json()
print('access token response: ')
print(json.dumps(resp_dict, indent=4, sort_keys=True))
s.headers.update({'Authorization': 'Bearer {}'.format(resp_dict['access_token'])})
resp = s.get('http://localhost:8080/v1/config')
print('config response after passing access token: ')
print(json.dumps(resp.json(), indent=4, sort_keys=True))