The Auth System¶
概述¶
Swift 支持多种认证系统,它们共享以下共同特性
认证/授权部分可以是外部系统,也可以作为 WSGI 中间件在 Swift 内部运行
Swift 的用户在每个请求中传递一个认证令牌
Swift 使用外部认证系统或认证子系统验证每个令牌并缓存结果
令牌不会从请求到请求改变,但会过期
令牌可以通过 X-Auth-Token 或 X-Storage-Token 标头传递到 Swift。两者格式相同:只是一个代表令牌的简单字符串。有些认证系统使用 UUID 令牌,有些使用某个唯一内容的 MD5 哈希值,有些使用“其他内容”,但关键点是令牌是一个字符串,可以原样发送回认证系统进行验证。
Swift 将向认证系统发出调用,提供要验证的认证令牌。对于有效的令牌,认证系统会响应一个从现在开始的秒数形式的总体过期时间。为了避免一遍又一遍地验证同一个令牌的开销,Swift 会将令牌缓存一段可配置的时间,但不会超过过期时间。
Swift 项目包含两种认证系统
也可以按照 Extending Auth 中所述编写自己的认证系统。
TempAuth¶
TempAuth 主要用于 Swift 的功能测试环境,也可以用于其他测试环境(例如 SAIO (Swift All In One))。不建议在生产系统中使用 TempAuth。但是,TempAuth 功能齐全,可以用作开发自己的认证系统的模型。
TempAuth 在帐户内具有管理员和非管理员用户的概念。管理员可以在帐户内执行任何操作。非管理员用户只能执行读取操作。但是,某些特权元数据(例如 X-Container-Sync-Key)对非管理员用户不可访问。
具有特殊组 .reseller_admin 的用户可以在任何帐户上操作。有关示例用法,请参阅 swift.common.middleware.tempauth。如果请求来自经销商,认证系统会将请求环境 reseller_request 设置为 True。这可以被其他中间件使用。
其他用户可以通过 ACL 获得在帐户或容器上执行操作的能力。TempAuth 支持两种类型的 ACL
基于容器的
X-Container-Read和X-Container-Write元数据的每个容器 ACL。有关更多信息,请参阅 Container ACLs。基于帐户的
X-Account-Access-Control元数据的每个帐户 ACL。有关更多信息,请参阅 Account ACLs。
TempAuth 现在允许 OPTIONS 请求在没有令牌的情况下通过。
TempAuth 中间件负责创建自己的令牌。用户发出包含其用户名和密码的请求,TempAuth 响应一个令牌。然后使用此令牌对用户的帐户、容器和对象执行后续请求。
Keystone Auth¶
Swift 能够对 OpenStack Keystone 进行身份验证。在此环境中,Keystone 负责创建和验证令牌。 KeystoneAuth 中间件负责在 Swift 中实现认证系统,如这里所述。
KeystoneAuth 中间件支持基于容器的 ACL,基于容器的 X-Container-Read 和 X-Container-Write 元数据。有关更多信息,请参阅 Container ACLs。
Keystone 身份验证不支持帐户级别 ACL。
为了使用 keystoneauth 中间件,需要配置来自 KeystoneMiddleware 的 auth_token 中间件。
authtoken 中间件执行身份验证令牌验证并检索实际的用户身份验证信息。它可以在 KeystoneMiddleware 发行版中找到。
KeystoneAuth 中间件执行授权并将 Keystone 角色映射到 Swift 的 ACL。
配置 Swift 使用 Keystone¶
配置 Swift 使用 Keystone 相对简单。第一步是确保已安装 auth_token 中间件。它可以放入您的 python 路径或通过 KeystoneMiddleware 包安装。
首先需要确保在 Keystone 中有一个类型为 object-store 的服务端点,指向您的 Swift 代理。例如,在您的 /etc/keystone/default_catalog.templates 中
catalog.RegionOne.object_store.name = Swift Service
catalog.RegionOne.object_store.publicURL = http://swiftproxy:8080/v1/AUTH_$(tenant_id)s
catalog.RegionOne.object_store.adminURL = http://swiftproxy:8080/
catalog.RegionOne.object_store.internalURL = http://swiftproxy:8080/v1/AUTH_$(tenant_id)s
在您的 Swift 代理服务器上,您需要调整主管道并在您的 /etc/swift/proxy-server.conf 中添加 auth_token 和 keystoneauth,如下所示
[pipeline:main]
pipeline = [....] authtoken keystoneauth proxy-logging proxy-server
添加 authtoken 中间件的配置
[filter:authtoken]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
www_authenticate_uri = http://keystonehost:5000/
auth_url = http://keystonehost:5000/
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = swift
password = password
cache = swift.cache
include_service_catalog = False
delay_auth_decision = True
这些变量的实际值需要根据您的具体情况进行设置,但简而言之
www_authenticate_uri应该指向一个 Keystone 服务,用户可以从中检索令牌。此值用于 auth_token 在拒绝响应中发送的 WWW-Authenticate 标头。auth_url指向 Keystone Admin 服务。中间件使用此信息来实际查询 Keystone 关于身份验证令牌的有效性。不必将任何 Keystone API 版本号附加到此 URI。身份验证凭据 (
project_domain_id、user_domain_id、username、project_name、password) 将用于检索管理员令牌。该令牌将用于在后台授权用户令牌。这些凭据必须与 Swift 服务的 Keystone 凭据匹配。这里显示示例值假定名为“swift”的用户在名为“service”的项目上具有管理员角色,两者都在 Keystone 域中,ID 为“default”。有关其他示例,请参阅 KeystoneMiddleware 文档。cache设置为swift.cache。这意味着中间件将从请求环境中获取 Swift memcache。include_service_catalog如果未设置,则默认为True。这意味着在验证令牌时,将检索服务目录并存储在X-Service-Catalog标头中。如果您使用应用程序凭证中的访问规则,则需要这样做。您可能还需要增加 max_header_size。
注意
authtoken 配置变量 delay_auth_decision 必须设置为 True。默认值为 False,但这会破坏公共访问、StaticWeb、FormPost、TempURL 以及使用 Discoverability 的经过身份验证的功能请求。
最后,您可以添加 keystoneauth 配置。这是一个简单的配置
[filter:keystoneauth]
use = egg:swift#keystoneauth
operator_roles = admin, swiftoperator
在 operator_roles 中使用适当的角色列表。例如,在某些系统中,角色 _member_ 或 Member 用于指示用户允许对项目资源进行操作。
使用复合令牌的 OpenStack 服务¶
Cinder 和 Glance 等一些 OpenStack 服务可能会使用“服务帐户”。在这种模式下,您配置一个单独的帐户,服务在其中存储其管理的项目数据。此帐户不由最终用户直接使用。相反,所有访问都是通过服务完成的。
要访问“服务”帐户,服务必须提供两个令牌:一个来自最终用户,另一个来自其自身的服务用户。只有同时存在这两个令牌,才能访问该帐户。本节介绍如何设置配置选项以正确控制对“正常”和“服务”帐户的访问。
在此示例中,最终用户在帐户名称中使用 AUTH_ 前缀,而服务使用 SERVICE_ 前缀
[filter:keystoneauth]
use = egg:swift#keystoneauth
reseller_prefix = AUTH, SERVICE
operator_roles = admin, swiftoperator
SERVICE_service_roles = service
这些变量的实际值需要根据您的具体情况进行设置,如下所示
reseller_prefix 列表中的第一项必须与 Keystone 的端点匹配(请参阅上面的
/etc/keystone/default_catalog.templates)。通常这是AUTH。reseller_prefix 列表中的第二项是 OpenStack 服务使用的前缀。您必须使用其他 OpenStack 服务使用的任何内容配置此值 (
SERVICE在示例中)。将 operator_roles 选项设置为包含最终用户在其使用的项目上拥有的角色。
将 SERVICE_service_roles 值设置为仅服务用户拥有的角色。不要使用分配给“正常”最终用户的角色。在此示例中,使用角色
service。服务用户仅被授予一个项目的此角色。您不需要使服务用户成为每个项目的成员。
此配置的工作方式如下
最终用户将用户令牌呈现给 OpenStack 服务。然后,服务向带有
SERVICE前缀的帐户发出 Swift 请求。服务转发原始用户令牌与请求一起。它还添加了自己的服务令牌。
Swift 验证这两个令牌。验证后,用户令牌提供
admin或swiftoperator角色。验证后,服务令牌提供service角色。Swift 将上述配置解释如下
用户令牌是否提供了 operator_roles 列表中列出的角色之一?
服务令牌是否具有 SERVICE_service_roles 选项描述的
service角色。
如果满足这两个条件,则授予请求。否则,Swift 会拒绝该请求。
在上面的示例中,所有服务共享同一个帐户。您可以将每个服务分离到其自己的帐户中。例如,以下为 Glance 和 Cinder 服务提供了专用帐户。此外,您必须将 glance_service 和 cinder_service 分配给适当的服务用户
[filter:keystoneauth]
use = egg:swift#keystoneauth
reseller_prefix = AUTH, IMAGE, VOLUME
operator_roles = admin, swiftoperator
IMAGE_service_roles = glance_service
VOLUME_service_roles = cinder_service
使用 keystoneauth 进行访问控制¶
默认情况下,能够对帐户执行操作(例如,创建容器)的唯一用户是那些拥有与 Keystone 项目对应的 Keystone 角色,并且该角色与 operator_roles 选项中指定的角色匹配的用户。
具有 operator_roles 中的一个角色的用户可以使用 X-Container-Read 和 X-Container-Write 标头,将容器 ACL 设置为授予其他用户在特定容器中读取和/或写入对象的权限。除了 here 中描述的 ACL 格式之外,keystoneauth 支持使用以下格式的 ACL
other_project_id:other_user_id.
其中 other_project_id 是 Keystone 项目的 UUID,other_user_id 是 Keystone 用户的 UUID。这将允许其他用户访问容器,前提是他们的令牌作用域位于其他项目上。可以将 other_project_id 和 other_user_id 替换为通配符字符 *,这将匹配任何项目或用户。
请务必在容器 ACL 中使用 Keystone UUID,而不是名称。
注意
为了保持向后兼容性,keystoneauth 默认情况下将表示为 other_project_name:other_user_name(即使用 Keystone 名称而不是 UUID)的容器 ACL 授予权限,前提是其他项目和用户都在 Keystone 的默认域中,并且正在访问的项目也在默认域中。
有关更多信息,请参阅 KeystoneAuth
具有在 reseller_admin_role(默认情况下为 ResellerAdmin)中定义的 Keystone 角色的用户可以在任何帐户上操作。如果请求来自具有此角色的用户,认证系统会将请求环境 reseller_request 设置为 True。这可以被其他中间件使用。
keystoneauth 部署的故障排除提示¶
一些常见的错误可能导致在首次将 keystone 与 Swift 部署时 API 请求失败
Keystone 服务中 Swift 端点的配置不正确。
默认情况下,keystoneauth 期望帐户部分的 URL 具有
AUTH_<keystone_project_id>的形式。有时,如 Install Guide 中所述,在 Keystone 中配置 Swift 端点时会遗漏AUTH_前缀。可以通过检查代理服务器日志文件中的失败请求 URL 并检查 URL 是否包含AUTH_前缀(或 keystoneauth 配置的任何经销商前缀)来轻松诊断此问题GOOD: proxy-server: 127.0.0.1 127.0.0.1 07/Sep/2016/16/06/58 HEAD /v1/AUTH_cfb8d9d45212408b90bc0776117aec9e HTTP/1.0 204 ... BAD: proxy-server: 127.0.0.1 127.0.0.1 07/Sep/2016/16/07/35 HEAD /v1/cfb8d9d45212408b90bc0776117aec9e HTTP/1.0 403 ...
Swift 代理服务器中
authtoken中间件选项配置不正确。authtoken中间件与 Keystone 服务通信,以验证客户端请求中提供的令牌。为此,authtoken必须使用/etc/swift/proxy-server.conf中[filter:authtoken]部分中配置的凭据向 Keystone 进行身份验证。这些凭据中的错误可能导致authtoken无法验证令牌,并且可能在代理服务器日志中显示为如下消息:proxy-server: Identity server rejected authorization
注意
通过将
authtoken选项设置为log_level = debug,可以查看更详细的日志消息。authtoken配置选项可以通过尝试使用它们通过openstack命令行直接与 Keystone 通信来检查。例如,给定 Configuring Swift to use Keystone 中显示的authtoken配置示例,以下命令应返回服务目录:openstack --os-identity-api-version=3 --os-auth-url=http://keystonehost:5000/ \ --os-username=swift --os-user-domain-id=default \ --os-project-name=service --os-project-domain-id=default \ --os-password=password catalog show object-store
如果此
openstack命令失败,则很可能存在authtoken配置问题。
扩展认证¶
TempAuth 编写为 wsgi 中间件,因此实现您自己的认证就像编写新的 wsgi 中间件并将它插入到代理服务器中一样简单。
有关扩展认证系统的详细信息,请参阅 Auth Server and Middleware。