Access Control Lists (ACLs)
通常,要创建、读取和修改容器和对象,必须在项目中拥有与帐户相关联的适当角色,即必须是帐户的所有者。但是,所有者可以通过使用访问控制列表(ACL)向其他用户授予访问权限。
ACL有两种类型:
容器ACLs
容器ACL存储在X-Container-Write
和 X-Container-Read
元数据中。ACL的范围仅限于设置元数据的容器和容器中的对象。此外:
X-Container-Write
授予对容器内的对象执行PUT、POST和DELETE操作的能力。它不允许对容器本身执行POST或DELETE操作。一些ACL元素还授予对容器执行HEAD或GET操作的能力。X-Container-Read
授予对容器内的对象执行GET和HEAD操作的能力。一些ACL元素还授予对容器本身执行HEAD或GET操作的能力。但是,容器ACL不允许访问特权元数据(例如X-Container-Sync-Key
)。
容器ACL使用“V1”ACL语法,该语法是以逗号分隔的元素字符串,如以下示例所示:
.r:*,.rlistings,7ec59e87c6584c348b563254aae4c221:*
元素之间可能会出现空格,如下例所示:
.r : *, .rlistings, 7ec59e87c6584c348b563254aae4c221:*
However, these spaces are removed from the value stored in the X-Container-Write
and X-Container-Read
metadata. In addition, the .r:
string can be written as .referrer:
, but is stored as .r:
.
但是,这些空格是从存储在 X-Container-Write
和X-Container-Read
元数据中的值中删除的。此外,.r:
字符串可以写成.referrer:
,但存储为.r:
。
虽然所有认证系统都使用相同的语法,但由于不同的认证系统使用不同的概念,某些元素的含义不同,如以下各节所述:
通用ACL元素
下表描述了Keystone auth和TempAuth都支持的ACL元素。这些元素只能与X-Container-Read
一起使用(除了.rlistings
,如果与X-Container-Write
一起使用,则会出现错误):
元素 | 描述 |
---|---|
.r:* | 任何用户都可以访问对象。请求中不需要令牌。 |
.r: | 授予引用者(referrer )对对象的访问权限。引用者(referrer )由请求中的Referer 请求头标识。不需要令牌。 |
.r:- | 支持此语法(referrer前面加了“-”)。但是,如果另一个元素(例如,.r:* )允许访问,则它不会拒绝访问。 |
.rlistings | 任何用户都可以对容器执行HEAD或GET操作,前提是该用户还具有对对象的读访问权限 (例如,还具有 .r:* 或.r:<referre> 。不需要令牌。 |
Keystone认证ACL元素
下表介绍了仅由Keystone认证支持的ACL元素。Keystone 认证还支持通用ACL元素中描述的元素.
令牌必须包含在请求中,才能使这些ACL元素中的任何一个生效。
元素 | 描述 |
---|---|
: | 指定的用户被授予访问权限,前提是请求中包含范围为项目的令牌。当在X-Container-Read 中使用时,也授予对容器的访问权限。 |
😗 | 任何在指定Keystone项目中具有角色的用户都有访问权限。请求中必须包含范围为项目的令牌。在X-Container-Read 中使用时,也会授予对容器的访问权限。 |
*: | 指定的用户具有访问权限。请求中必须包含用户的令牌(范围为任何项目)。在X-Container-Read 中使用时,也会授予对容器的访问权限。 |
*:* | 任何用户都有访问权限。在 X-Container-Read 中使用时,也会授予对容器的访问权限。*:* 元素与.r:* 元素不同,因为*:* 要求在请求中包含有效的令牌,而.r:* 不要求令牌。此外,.r:* 不授予对容器列表的访问权限。 |
<role_name> | 在存储容器的项目中具有指定角色name的用户被授予访问权限。请求中必须包含范围为项目的用户令牌。在 X-Container-Read 中使用时,也会授予对容器的访问权限。 |
说明
不得再使用Keystone项目(租户)或用户names(即
<project-name>:<user-name>
),因为随着Keystone中域的引入,名称不是全局唯一的。您应该使用用户和项目ids。为了向后兼容,如果可以确定被授权项目、被授权用户和被访问的项目尚未在域中(例如,
X-Auth-Token
已通过Keystone V2 API获得),或者都在传统帐户迁移到的默认域中,则keysneauth将授予使用名称的ACL。
TempAuth ACL元素
下表描述了仅TempAuth支持的ACL元素。TempAuth认证还支持通用ACL元素中描述的元素.
元素 | 描述 |
---|---|
指定用户被授予访问权限。不支持通配符“*”。来自用户的令牌必须包含在请求中。 |
容器ACL示例
可以通过将 X-Container-Write
和/或 X-Container-Read
头与对容器URL的PUT或POST请求一起包含来设置容器ACL。以下示例使用swift
命令行客户端,该客户端支持通过其 --write-acl
和--read-acl
选项设置这些标头。
示例: 公共容器
下面的代码允许任何人列出www
容器中的对象并下载对象。用户不需要在其请求中包含令牌。此ACL通常被称为使容器“公开”。它是有用的,当使用StaticWeb😃
swift post www --read-acl ".r:*,.rlistings"
示例:共享可写容器
下面的命令允许任何人上传或下载对象。但是,要下载对象,必须知道对象的确切名称,因为用户无法列出容器中的对象。用户上传请求中必须包含Keystone令牌。但是,它不需要限定在与容器相关的项目范围内:
swift post www --read-acl ".r:*" --write-acl "*:*"
示例: 与项目成员共享容器
下面的命令允许77b8f82565f14814bece56e50c4c240f
项目的任何成员上传和下载对象或列出www
容器的内容。范围为77b8f82565f14814bece56e50c4c240f
项目的令牌必须包含在请求中:
swift post www --read-acl "77b8f82565f14814bece56e50c4c240f:*" \
--write-acl "77b8f82565f14814bece56e50c4c240f:*"
示例: 与具有指定角色的用户共享容器
下面的命令允许任何在项目中被分配了my_read_access_role
的用户下载对象或列出www
容器的内容。下载或列表请求中必须包含项目范围内的用户令牌:
swift post www --read-acl "my_read_access_role"
示例: 允许引用域下载对象
下面的代码允许来自example.com域的任何请求访问容器中的对象:
swift post www --read-acl ".r:.example.com"
然而,来自用户的请求必须包含适当的Referer头,如下例请求所示:
curl -i $publicURL/www/document --head -H "Referer: http://www.example.com/index.html"
说明
许多浏览器的请求中都包含Referer头。但是,由于很容易在Referer头中创建具有任何所需值的请求,因此Referer ACL的安全性非常弱。
示例: 与其他用户共享容器
与另一个用户共享容器需要了解有关用户的一些参数。
共享用户必须知道:
- 其它用户的
OpenStack用户id
共享用户必须与其他用户通信:
- 共享容器的名称
OS_STORAGE_URL
通常,OS_STORAGE_URL
不会直接暴露给用户,因为swift客户端
默认情况下会根据用户凭据自动构造OS_STORAGE_URL
。
我们假设在当前目录中有两个用户的客户端环境脚本 sharing.openrc
和other.openrc
。
shareing.openrc
应类似于以下内容:
export OS_USERNAME=sharing
# WARNING: Save the password in clear text only for testing purposes
export OS_PASSWORD=password
export OS_TENANT_NAME=projectName
export OS_AUTH_URL=https://identityHost:portNumber/v2.0
# The following lines can be omitted
export OS_TENANT_ID=tenantIDString
export OS_REGION_NAME=regionName
export OS_CACERT=/path/to/cacertFile
other.openrc
应类似于以下内容:
export OS_USERNAME=other
# WARNING: Save the password in clear text only for testing purposes
export OS_PASSWORD=otherPassword
export OS_TENANT_NAME=otherProjectName
export OS_AUTH_URL=https://identityHost:portNumber/v2.0
# The following lines can be omitted
export OS_TENANT_ID=tenantIDString
export OS_REGION_NAME=regionName
export OS_CACERT=/path/to/cacertFile
有关更多信息,请参阅使用OpenStack RC文件
首先我们计算出另一个用户id:
. other.openrc
OUID="$(openstack user show --format json "${OS_USERNAME}" | jq -r .id)"
或者:
. other.openrc
OUID="$(openstack token issue -f json | jq -r .user_id)"
然后求出共享用户的存储url:
sharing.openrc
SURL="$(swift auth | awk -F = '/OS_STORAGE_URL/ {print $2}')"
以共享用户的身份创建一个名为shared
的共享容器,使用适当的acl以只读模式与另一个用户共享容器。
sharing.openrc
swift post --read-acl "*:${OUID}" shared
作为共享用户运行,创建并上传一个测试文件:
touch void
swift upload shared void
作为另一个用户运行,列出 shared
容器中的文件:
other.openrc
swift --os-storage-url="${SURL}" list shared
以其他用户身份运行,下载 shared
容器到/tmp
目录中:
cd /tmp
swift --os-storage-url="${SURL}" download shared
账户ACLs
注
Keystone认证目前不支持帐户ACLs
X-Account-Access-Control
头用于以特定于认证系统的格式指定帐户级ACLs。这些头文件只有账户所有者(swift_owner
为true
的账户所有者)才能看到和设置。帐户 ACLs的行为依赖于auth-system。在TempAuth的情况下,如果经过认证的用户在ACL中列出的组中具有成员资格,则允许该用户具有该ACL的访问级别。
帐户ACL使用“V2”ACL语法,它是一个JSON字典,键名为“admin”,“read-write”和“read-only”。(注意大小写敏感性。)X-Account-Access-Control
头的示例值如下所示,其中a
, b
和c
是用户名:
{"admin":["a","b"],"read-only":["c"]}
键可能不存在(如上例所示)。
生成ACL字符串的推荐方法如下:
from swift.common.middleware.acl import format_acl
acl_data = { 'admin': ['alice'], 'read-write': ['bob', 'carol'] }
acl_string = format_acl(version=2, acl_dict=acl_data)
使用format_acl()
方法将确保JSON被编码为ASCII(例如使用u1234
表示Unicode)。虽然允许手动发送包含X-Account-Access-Control
头的curl
命令,但这样做时应该谨慎,因为可能会出现人为错误。
在存储在X-Account-Access-Control
中的JSON字典中,键具有以下含义:
访问级别 | 描述 |
---|---|
read-only | 这些身份可以读取帐户中的所有内容(特权头除外)。具体来说,具有只读帐户访问权限的用户可以获得帐户中的容器列表,列出任何容器的内容,检索任何对象,并查看帐户、任何容器或任何对象的(非特权)头。 |
read-write | 这些身份可以读写(或创建)任何容器。具有读写帐户访问权限的用户可以创建新容器,设置任何非特权容器头,覆盖对象,删除容器等。读写用户不能设置帐户头(或对帐户执行任何PUT/POST/DELETE请求)。 |
admin | 这些身份具有" swift_owner "权限。具有admin帐户访问权限的用户可以执行帐户所有者可以执行的任何操作,包括设置帐户头和任何特权头—从而授予其他用户只读、读写或管理访问权限。 |