配置 Keystone 以进行联合身份验证¶
Keystone 作为服务提供商 (SP)¶
先决条件¶
如果您不熟悉联合身份验证的概念,请先参阅 Keystone 联合身份验证简介。
在本节中,我们将配置 Keystone 作为服务提供商,使用外部身份提供商(例如 SAML 断言或 OpenID Connect 声明)颁发的身份属性。为了测试目的,我们建议使用 samltest.id 作为 SAML 身份提供商,或 Google 作为 OpenID Connect 身份提供商,并且这里的示例将引用这些提供商。如果您计划设置 Keystone 作为身份提供商 (IdP),则首先使用虚拟 SAML 提供商设置 Keystone,然后重新配置它以稍后指向 Keystone 身份提供商会更容易。
以下配置步骤是在运行 Ubuntu 16.04 和 Apache 2.4.18 的机器上执行的。
要启用联合身份验证,您需要将 Keystone 放在 Web 服务器(例如 Apache)之后,而不是直接使用 uWSGI 或 Gunicorn 运行 WSGI 应用程序。请参阅安装指南中的 RedHat 或 Ubuntu,以配置 Keystone 的 Apache Web 服务器。
在指南的其余部分,您需要确定三条信息并一致地在整个配置中使用它们
协议名称。这必须是有效的 Keystone 身份验证方法,并且必须与以下之一匹配:
saml2、openid、mapped或 自定义身份验证方法,您必须 注册为外部驱动程序。身份提供商名称。这可以是任意的。
服务提供商的实体 ID。这应该是一个 URN,但不一定需要解析到任何内容。
您还需要决定使用哪个 HTTPD 模块作为服务提供商。本指南提供了 mod_shib 和 mod_auth_mellon 作为 SAML 服务提供商的示例,以及 mod_auth_openidc 作为 OpenID Connect Relying Party 的示例。
注意
在本指南中,Keystone 服务提供商配置在名为 sp.keystone.example.org 的主机上,监听标准的 HTTPS 端口。所有 Keystone 路径都将以 Keystone 版本前缀 /v3 开头。如果您已配置 Keystone 监听端口 5000,或响应路径 /identity(例如),请在您自己的配置中考虑到这一点。
在 Keystone 中创建联合身份验证资源¶
您需要通过 Keystone API 创建三个资源,以将身份提供商标识给 Keystone,并将远程用户属性与 Keystone 对象对齐
另请参阅 keystone 联合身份验证 API 参考。
创建一个身份提供商¶
在 Keystone 中创建一个身份提供商对象,该对象代表我们将用于验证最终用户的身份提供商
$ openstack identity provider create --remote-id https://samltest.id/saml/idp samltest
选项 remote-id 的值是由身份提供商提供的唯一标识符,称为 实体 ID 或 远程 ID。对于 SAML 身份提供商,可以通过查询其元数据端点找到它
$ curl -s https://samltest.id/saml/idp | grep -o 'entityID=".*"'
entityID="https://samltest.id/saml/idp"
对于 OpenID Connect IdP,它是身份提供商的 Issuer Identifier。远程 ID 必须是全局唯一的:两个身份提供商不能与相同的远程 ID 相关联。远程 ID 通常显示为 URN,但不一定需要是可解析的 URL。
本地名称,在我们的示例中称为 samltest,由您决定,将在映射和协议中使用,稍后用于身份验证。
注意
一个身份提供商 Keystone 对象可以指定多个 remote-ids,这允许相同的 keystone 身份提供商资源与多个外部身份提供商一起使用。例如,身份提供商资源 university-idp 可能具有以下 remote_ids:['university-x', 'university-y', 'university-z']。这消除了在 Keystone 中配置 N 个身份提供商的需要。
另请参阅 身份提供商的 API 参考。
创建一个映射¶
接下来,创建一个映射。映射是一组将远程用户的属性链接到 Keystone 了解的用户属性的规则。它对于授予远程用户访问 Keystone 资源的授权非常有用,无论是通过将他们与本地 Keystone 组关联并继承其角色分配,还是根据这些规则动态地在 Keystone 中配置项目。
注意
默认情况下,用户从映射获得的组 membership 仅在 token 的有效期内有效。可以将其持久化一段时间。要启用此功能,请设置身份提供商的 authorization_ttl` 属性, 或 keystone.conf 文件中的 ``[federation] default_authorization_ttl。此值以分钟为单位,将导致用户从组中删除与在 Keystone 中发生的时间滞后。请仔细考虑您的安全要求。
每个协议只有一个映射对象。映射对象可以由不同的身份提供商和协议组合多次使用。
作为一个简单的示例,创建一个映射,其中包含一个规则,将所有远程用户映射到 Keystone 中的单个组中的本地用户
$ cat > rules.json <<EOF
[
{
"local": [
{
"user": {
"name": "{0}"
},
"group": {
"domain": {
"name": "Default"
},
"name": "federated_users"
}
}
],
"remote": [
{
"type": "REMOTE_USER"
}
]
}
]
EOF
$ openstack mapping create --rules rules.json samltest_mapping
此映射规则评估 HTTPD auth 模块设置的 REMOTE_USER 变量,并使用它来填充 Keystone 中本地用户的名称。它还确保所有远程用户都成为 federated_users 组的有效成员,从而继承该组的角色分配。
在此示例中,federated_users 组必须存在于 Keystone Identity 后端中,并且必须在某个项目、域或系统中具有角色分配,以便联合用户在 Keystone 中具有授权。例如,要创建该组
$ openstack group create federated_users
创建一个用户应该被分配到的项目
$ openstack project create federated_project
将该组分配到项目中的 member 角色
$ openstack role add --group federated_users --project federated_project member
可以在 映射组合 页面上找到详细指南。
另请参阅 映射规则的 API 参考。
创建一个协议¶
现在创建一个联合身份验证协议。联合身份验证协议对象将身份提供商链接到映射。
您可以像这样创建一个协议
$ openstack federation protocol create saml2 \
--mapping samltest_mapping --identity-provider samltest
如 先决条件 中所述,您为协议指定的名称不是任意的,必须是有效的身份验证方法。
另请参阅 联合身份验证协议的 API 参考。
配置 HTTPD auth 模块¶
本指南目前仅包含 Apache Web 服务器的示例,但可以在其他 Web 服务器中使用 SAML、OpenIDC 和其他身份验证模块。请参阅安装指南,了解在 Apache 之后运行 Keystone 的方法,适用于 RedHat 或 Ubuntu。
配置受保护的端点¶
Keystone 服务虚拟主机配置中至少有一个端点必须受到保护
<Location /v3/OS-FEDERATION/identity_providers/IDENTITYPROVIDER/protocols/PROTOCOL/auth>
Require valid-user
AuthType [...]
...
</Location>
这是联合用户请求未限定 token 的端点。
如果配置 WebSSO,还应保护以下一个或两个端点
<Location /v3/auth/OS-FEDERATION/websso/PROTOCOL>
Require valid-user
AuthType [...]
...
</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/IDENTITYPROVIDER/protocols/PROTOCOL/websso>
Require valid-user
AuthType [...]
...
</Location>
第一个示例仅指定一个协议,Keystone 将使用传入的远程 ID 来确定身份提供商。第二个直接指定身份提供商,然后在配置 horizon 用于 WebSSO 时必须将其提供给 horizon。
路径必须与用于访问 Keystone 服务的路径完全匹配。例如,如果在 创建一个身份提供商 中创建的身份提供商是 samltest,并且在 创建一个协议 中创建的协议是 saml2,则 Locations 将是
<Location /v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth>
Require valid-user
AuthType [...]
...
</Location>
<Location /v3/auth/OS-FEDERATION/websso/saml2>
Require valid-user
AuthType [...]
...
</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/samltest/protocols/saml2/websso>
Require valid-user
AuthType [...]
...
</Location>
但是,如果您已配置 Keystone 服务以使用虚拟路径,例如 /identity,则应将该部分包含在路径中
<Location /identity/v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth>
Require valid-user
AuthType [...]
...
</Location>
...
配置 auth 模块¶
如果您的身份提供商是 SAML IdP,则可以使用两种主要的 Apache 模块作为 SAML 服务提供商:mod_shib 和 mod_auth_mellon。对于 OpenID Connect 身份提供商,使用 mod_auth_openidc。您还可以使用其他身份验证模块,例如 kerberos、X.509 或其他模块。请查阅您选择的提供商的文档,以获取详细的安装和配置指南。
根据您选择的服务提供商模块,您需要安装适用的 Apache 模块包并遵循其他配置步骤。本指南包含两个主要联合身份验证协议的示例
SAML2.0 - 请参阅以下实现的指南
OpenID Connect:设置 mod_auth_openidc。
配置 Keystone¶
虽然 Apache 模块完成了大部分繁重的工作,但需要进行一些小的更改才能允许 Keystone 允许和理解联合身份验证。
添加身份验证方法¶
将身份验证方法添加到 keystone.conf 中的 [auth] 部分。这里的身份验证方法必须与在 创建一个协议 中创建的协议同名。您还应删除 external 作为允许的方法。
[auth]
methods = password,token,saml2,openid
配置远程 ID 属性¶
Keystone 对您为服务提供商配置的 HTTPD auth 模块大多漠不关心,但必须知道要从 auth 模块查找哪个标头键,以确定身份提供商的远程 ID,以便将其传入请求与身份提供商资源关联起来。键名由 auth 模块的选择决定
对于
mod_shib:使用Shib-Identity-Provider对于
mod_auth_mellon:属性名称在虚拟主机配置中通过MellonIdP参数配置,如果设置为例如IDP,则使用MELLON_IDP对于
mod_auth_openidc:属性名称与 Apache 配置中的OIDCClaimPrefix参数相关,如果设置为例如OIDC-,则使用HTTP_OIDC_ISS
建议通过创建以协议命名的新部分,在每个协议的基础上设置此选项
[saml2]
remote_id_attribute = Shib-Identity-Provider
[openid]
remote_id_attribute = HTTP_OIDC_ISS
或者,可以在 [federation] 级别设置通用选项。
[federation]
remote_id_attribute = HTTP_OIDC_ISS
添加受信任的仪表板(WebSSO)¶
如果您打算将 horizon 配置为 WebSSO 前端,您必须指定受信任 horizon 服务器的 URL。此值可以重复多次。此设置可确保 keystone 仅将令牌数据发送回受信任的服务器。这是作为一种预防措施,特别是为了防止中间人 (MITM) 攻击。该值必须与 horizon 服务器发送的原始地址完全匹配,包括任何尾随斜杠。
[federation]
trusted_dashboard = https://horizon1.example.org/auth/websso/
trusted_dashboard = https://horizon2.example.org/auth/websso/
添加回调模板 (WebSSO)¶
如果您打算将 horizon 配置为 WebSSO 前端,并且您的发行版 keystone 包尚未为您完成此操作,请将 sso_callback_template.html 模板复制到 [federation]/sso_callback_template 选项在 keystone.conf 中指定的目录中。您也可以使用此模板作为示例来创建您自己的自定义 HTML 重定向页面。
在更改 keystone 配置后,重新启动 keystone WSGI 服务或 Apache 前端服务。
# systemctl restart apache2
将 Horizon 配置为 WebSSO 前端¶
注意
有关配置 horizon 的详细信息,请参阅 horizon 的官方文档。
Keystone 本身无法支持基于浏览器的单点登录身份验证流程,例如 SAML2.0 WebSSO 配置文件,因此我们必须借助 horizon 的帮助。可以通过在 horizon 的 local_settings.py 配置文件中启用它,并添加在登录屏幕上呈现给用户的可能的身份验证选项来配置 horizon 以支持 SSO。
确保在 horizon 的 local_settings.py 文件中将 WEBSSO_ENABLED 选项设置为 True,这将为 horizon 用户提供更新的登录屏幕。
WEBSSO_ENABLED = True
配置用户在登录屏幕上可以选择的身份验证选项。在此列表中配置的对映射用户友好的字符串到身份验证选项,可以是以下选项之一
字符串
credentials,它强制 horizon 显示自己的用户名和密码字段,用户将使用这些字段作为本地 keystone 用户进行身份验证您在 创建协议 中创建的协议名称,例如
saml2或openid,这将导致 horizon 调用 keystone 的 WebSSO API 而不使用身份提供程序 来验证用户映射到在
WEBSSO_IDP_MAPPING中配置的身份提供程序和协议组合的字符串,这将导致 horizon 调用 keystone 的 针对给定身份提供程序的 WebSSO API。
WEBSSO_CHOICES = (
("credentials", _("Keystone Credentials")),
("openid", _("OpenID Connect")),
("saml2", _("Security Assertion Markup Language")),
("myidp_openid", "Acme Corporation - OpenID Connect"),
("myidp_saml2", "Acme Corporation - SAML2")
)
WEBSSO_IDP_MAPPING = {
"myidp_openid": ("myidp", "openid"),
"myidp_saml2": ("myidp", "saml2")
}
还可以配置下拉菜单的初始选择
WEBSSO_INITIAL_CHOICE = "credentials"
完成 horizon 配置后,请记住重新启动 Web 服务器
# systemctl restart apache2
身份验证¶
使用 CLI 使用 SAML2.0 身份提供程序进行身份验证¶
可以使用 python-openstackclient 将 SAML 身份提供程序中的联合用户身份验证到 keystone。
注意
SAML 身份提供程序必须配置为支持 ECP 身份验证配置文件。
要使用 CLI 工具,您必须拥有 keystone 中的身份提供程序资源的名称、在 keystone 中配置的联合协议的名称以及身份提供程序的 ECP 端点。如果您是云管理员,则身份提供程序和协议的名称分别在 创建身份提供程序 和 创建协议 中配置。如果您不是管理员,则必须从管理员处获取此信息。
身份提供程序的 ECP 端点可以从其元数据中获得,无需涉及管理员。此端点是元数据文档中的 urn:oasis:names:tc:SAML:2.0:bindings:SOAP 绑定
$ curl -s https://samltest.id/saml/idp | grep urn:oasis:names:tc:SAML:2.0:bindings:SOAP
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://samltest.id/idp/profile/SAML2/SOAP/ECP"/>
查找可用范围¶
如果您是新用户,并且不知道您有权访问哪些资源,可以使用无范围的查询来列出您已被授予角色分配的项目或域
export OS_AUTH_TYPE=v3samlpassword
export OS_IDENTITY_PROVIDER=samltest
export OS_IDENTITY_PROVIDER_URL=https://samltest.id/idp/profile/SAML2/SOAP/ECP
export OS_PROTOCOL=saml2
export OS_USERNAME=morty
export OS_PASSWORD=panic
export OS_AUTH_URL=https://sp.keystone.example.org/v3
export OS_IDENTITY_API_VERSION=3
openstack federation project list
openstack federation domain list
获取范围令牌¶
如果您已经知道要限定的项目、域或系统,可以直接请求范围令牌
export OS_AUTH_TYPE=v3samlpassword
export OS_IDENTITY_PROVIDER=samltest
export OS_IDENTITY_PROVIDER_URL=https://samltest.id/idp/profile/SAML2/SOAP/ECP
export OS_PROTOCOL=saml2
export OS_USERNAME=morty
export OS_PASSWORD=panic
export OS_AUTH_URL=https://sp.keystone.example.org/v3
export OS_IDENTITY_API_VERSION=3
export OS_PROJECT_NAME=federated_project
export OS_PROJECT_DOMAIN_NAME=Default
openstack token issue
使用 horizon 使用外部身份提供程序进行身份验证¶
当 horizon 配置为启用 WebSSO 时,在用户进行身份验证之前,登录屏幕上会出现一个下拉菜单。从菜单中选择身份验证方法,将被重定向到您的身份提供程序进行身份验证。
Keystone 作为身份提供程序 (IdP)¶
先决条件¶
当 keystone 配置为身份提供程序时,通常被称为“Keystone 到 Keystone”,因为它使用 SAML2.0 协议实现了多个 OpenStack 云之间的联合。
如果您不熟悉联合身份的概念,请先参阅 介绍。
在设置“Keystone 到 Keystone”时,首先 配置 keystone 服务提供程序 与 samltest.id 等沙盒身份提供程序会更容易。
此功能需要通过您的发行版软件包系统(例如 apt 或 yum)安装 xmlsec1 工具。
# apt-get install xmlsec1
注意
在本指南中,keystone 身份提供程序配置在名为 idp.keystone.example.org 的主机上,并侦听标准的 HTTPS 端口。所有 keystone 路径都将以 keystone 版本前缀开头,即 /v3。如果您已配置 keystone 侦听端口 5000,或响应路径 /identity(例如),请在您自己的配置中考虑这一点。
配置元数据¶
由于 keystone 充当 SAML 身份提供程序,因此其元数据必须配置在 [saml] 部分(不要与您在 配置远程 ID 属性 设置 keystone 作为服务提供程序时可能配置的可选 [saml2] 部分混淆)的 keystone.conf 中,以便通过 元数据 API 提供服务。
为了使 keystone 生成元数据,必须设置的两个参数是 idp_entity_id 和 idp_sso_endpoint
[saml]
idp_entity_id=https://idp.keystone.example.org/v3/OS-FEDERATION/saml2/idp
idp_sso_endpoint=https://idp.keystone.example.org/v3/OS-FEDERATION/saml2/sso
idp_entity_id 设置身份提供程序实体 ID,这是一个您选择的字符串,用于唯一标识任何服务提供程序的身份提供程序。
idp_sso_endpoint 需要生成有效的元数据,但其值当前未使用,因为 keystone 作为身份提供程序不支持 SAML2.0 WebSSO 身份验证配置文件。将来可能会更改,这就是为什么没有提供默认值并且必须由操作员设置的原因。
为了完整起见,还应更新以下组织和联系方式配置选项,以反映您的组织和管理员联系方式。
idp_organization_name=example_company
idp_organization_display_name=Example Corp.
idp_organization_url=example.com
idp_contact_company=example_company
idp_contact_name=John
idp_contact_surname=Smith
idp_contact_email=jsmith@example.com
idp_contact_telephone=555-555-5555
idp_contact_type=technical
务必注意默认的 certfile 和 keyfile 选项,并根据需要进行调整
certfile=/etc/keystone/ssl/certs/signing_cert.pem
keyfile=/etc/keystone/ssl/private/signing_key.pem
您必须生成 PKI 密钥对并将文件复制到这些路径。您可以使用 openssl 工具来执行此操作。Keystone 不提供用于此目的的实用程序。
检查 idp_metadata_path 设置并根据需要进行调整
idp_metadata_path=/etc/keystone/saml2_idp_metadata.xml
要为您的 keystone IdP 创建元数据,请运行 keystone-manage 命令并将输出重定向到文件。例如
# keystone-manage saml_idp_metadata > /etc/keystone/saml2_idp_metadata.xml
最后,重新启动 keystone WSGI 服务或 Web 服务器前端
# systemctl restart apache2
创建服务提供程序资源¶
创建一个服务提供程序资源,以将您的服务提供程序表示为 keystone 中的对象
$ openstack service provider create keystonesp \
--service-provider-url https://sp.keystone.example.org/Shibboleth.sso/SAML2/ECP
--auth-url https://sp.keystone.example.org/v3/OS-FEDERATION/identity_providers/keystoneidp/protocols/saml2/auth
--auth-url 是特定身份提供程序和协议名称(此处命名为 keystoneidp 和 saml2)的 联合身份验证端点。
--service-provider-url 是服务提供程序的断言消费者服务的 urn:oasis:names:tc:SAML:2.0:bindings:PAOS 绑定。可以从服务提供程序的元数据中获得它
$ curl -s https://sp.keystone.example.org/Shibboleth.sso/Metadata | grep urn:oasis:names:tc:SAML:2.0:bindings:PAOS
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://sp.keystone.example.org/Shibboleth.sso/SAML2/ECP" index="4"/>
身份验证¶
使用 CLI 使用 Keystone-to-Keystone 进行身份验证¶
使用 python-openstackclient 使用 IdP 进行身份验证,然后从 SP 获取范围令牌。
export OS_USERNAME=demo
export OS_PASSWORD=nomoresecret
export OS_AUTH_URL=https://idp.keystone.example.org/v3
export OS_IDENTITY_API_VERSION=3
export OS_PROJECT_NAME=federated_project
export OS_PROJECT_DOMAIN_NAME=Default
export OS_SERVICE_PROVIDER=keystonesp
export OS_REMOTE_PROJECT_NAME=federated_project
export OS_REMOTE_PROJECT_DOMAIN_NAME=Default
openstack token issue
使用 Horizon 切换云¶
无需额外配置即可启用 Keystone 到 Keystone 的 horizon。使用您的常规本地 keystone 凭据登录到身份提供程序的 horizon 实例。登录后,您将看到一个服务提供程序下拉菜单,可以使用它将仪表板视图切换到另一个云。
设置 OpenID Connect¶
在继续这些 OpenIDC 特定说明之前,请参阅 Keystone 作为服务提供程序 (SP)。
在使用 OpenID Connect 时,您必须拥有第三方 OpenID 提供程序或身份提供程序。OpenID Connect 提供程序的示例包括 Google、Keycloak、Microsoft Entra 和 GitLab。Keystone 将使用 mod_auth_openidc 使 Keystone 能够充当 OpenID Connect Relying Party,这是依赖于 OpenID Connect 提供程序进行身份验证的应用程序的名称。您必须在 OpenID Connect 提供程序中添加代表 Keystone 服务提供程序的 OpenID Connect 客户端。
声明是 OpenID Connect 提供程序提供给 OpenID Connect Relying Party 的用户详细信息或属性的片段。声明可以通过从 ID 令牌或从 UserInfo 端点检索来请求。通过指定映射到一组声明的范围来请求声明。
为了与 Keystone 文档的其余部分保持一致,将使用术语服务提供程序,这意味着充当服务提供程序的 Keystone 等效于 OpenID Connect Relying Party。
这些示例使用 Google 作为 OpenID Connect 提供程序。必须在 Google API 控制台 中将服务提供程序添加到身份提供程序。
配置 Apache HTTPD 以进行 mod_auth_openidc¶
注意
建议您仔细阅读 mod_auth_openidc 文档。
安装模块¶
安装 Apache 模块包。例如,在 Ubuntu 上
# apt-get install libapache2-mod-auth-openidc
软件包和模块名称因发行版而异。
配置 mod_auth_openidc¶
在 keystone VirtualHost 的 Apache 配置中,设置以下 OIDC 选项
OIDCClaimPrefix "OIDC-"
OIDCClaimDelimiter ";"
OIDCResponseType "id_token"
OIDCScope "openid email profile"
OIDCProviderMetadataURL https://#/.well-known/openid-configuration
OIDCOAuthVerifyJwksUri https://www.googleapis.com/oauth2/v3/certs
OIDCClientID <openid_client_id>
OIDCClientSecret <openid_client_secret>
OIDCCryptoPassphrase <random string>
OIDCRedirectURI https://sp.keystone.example.org/v3/redirect_uri
OIDCClaimPrefix 在所有声明前加上该值,然后当呈现给 Keystone 时,该值将加上 HTTP_ 前缀,并将破折号(“-”)转换为下划线(“_”),并转换为大写。结果是 iss 声明将作为 HTTP_OIDC_ISS 呈现给 Keystone,使用上述 OIDCClaimPrefix。声明是 JSON 数据片段,但 Apache 仅将字符串数据转发给 Keystone。因此,默认情况下,列表将转换为逗号(“,”)分隔的字符串,而 Keystone 的映射代码期望它们是分号(“;”)分隔的。要正确支持这一点,请将 OIDCClaimDelimiter 设置为使用分号(“;”)。OIDCResponseType 指定将使用的 OpenID Connect 流程。要使用 Implicit Flow,请指定值 id_token,要使用 Authorization Code Flow,请指定值 code。某些 OpenID Connect 提供程序默认情况下未启用 Implicit Flow。OIDCScope 是用户将授权身份提供程序发送给服务提供商的属性或声明的列表。OIDCClientID 和 OIDCClientSecret 必须从身份提供程序生成和获取,OIDCProviderMetadataURL 是服务提供程序将从中获取身份提供程序元数据的 URL。OIDCOAuthVerifyJwksUri 是服务提供程序将从中下载身份提供程序的公钥以检查用户的访问令牌是否有效,此配置必须在使用 AuthType auth-openidc 时使用,在使用 AuthType openid-connect 且配置了 OIDCProviderMetadataURL 时,此属性将不是必需的。OIDCRedirectURI 是一个虚荣 URL,必须指向没有内容的受保护路径,例如受保护的联合身份验证路径的扩展。它不应与任何 Keystone API 端点匹配,否则 mod_auth_openidc 将处理端点的请求,而不是 Keystone。这可能导致来自 Keystone 的异常错误和行为。
注意
如果使用的 mod_wsgi 版本低于 4.3.0,则必须指定 OIDCClaimPrefix 仅包含字母数字或破折号(“-”)。这是因为 mod_wsgi 阻止不符合此标准的标头。
配置受保护的端点¶
配置每个受保护的路径以使用 openid-connect AuthType
<Location ~ "/redirect_uri">
Require valid-user
AuthType openid-connect
</Location>
<Location /v3/OS-FEDERATION/identity_providers/google/protocols/openid/auth>
Require valid-user
AuthType openid-connect
</Location>
注意
为了添加对由不采用浏览器流程的应用程序使用的 Bearer Access Token 身份验证流程的支持,例如 OpenStack CLI,您需要将 AuthType 从 openid-connect 更改为 auth-openidc。
如果使用 horizon,请对 WebSSO 身份验证路径执行相同的操作
<Location /v3/auth/OS-FEDERATION/websso/openid>
Require valid-user
AuthType openid-connect
</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/google/protocols/openid/websso>
Require valid-user
AuthType openid-connect
</Location>
在更改 VirtualHost 后,请记住重新加载 Apache
# systemctl reload apache2
注意
在 keystone 中创建 映射规则 时,请注意“remote”属性将加上 HTTP_ 前缀,因此,例如,如果您将 OIDCClaimPrefix 设置为 OIDC-,则要检查的典型 remote 值是:HTTP_OIDC_ISS。
配置多个身份提供程序¶
为了在您的环境中配置多个身份提供程序,您需要像以下选项一样设置您的 OIDC 选项
OIDCClaimPrefix "OIDC-"
OIDCClaimDelimiter ";"
OIDCResponseType "id_token"
OIDCScope "openid email profile"
OIDCMetadataDir <IDP metadata directory>
OIDCCryptoPassphrase <random string>
OIDCRedirectURI https://sp.keystone.example.org/redirect_uri
OIDCOAuthVerifyCertFiles <kid>#</path/to-cert.pem> <kid2>#</path/to-cert2.pem> <kidN>#</path/to-certN.pem>
OIDCOAuthVerifyCertFiles 是一个用 空格 分隔的元组,包含发行者公钥的 key-id 和指向发行者证书的路径。分隔符 # 用于分隔 (kid) 和公共证书地址
在选项 OIDCMetadataDir 中配置的元数据文件夹必须包含您的所有身份提供程序配置,文件的名称将是发行者的名称(带路径),例如
- <IDP metadata directory>
|
- accounts.google.com.client
|
- accounts.google.com.conf
|
- accounts.google.com.provider
|
- keycloak.example.org%2Fauth%2Frealms%2Fidp.client
|
- keycloak.example.org%2Fauth%2Frealms%2Fidp.conf
|
- keycloak.example.org%2Fauth%2Frealms%2Fidp.provider
注意
如果需要,文件名必须进行 URL 编码,因为 Apache2 mod_auth_openidc 将从 http 请求中获取 URL 编码的 iss 查询参数并检查是否存在具有此名称的元数据,由于查询参数是 URL 编码的,因此元数据文件名也需要进行编码。例如,如果您的发行者在 URL 中包含 /,则需要将其转义为 %2F,通过对文件名应用 URL 转义。
这些文件的内容必须是 JSON,例如
accounts.google.com.client:
{
"client_id":"<openid_client_id>",
"client_secret":"<openid_client_secret>"
}
.client 文件处理发行者中的 SP 凭据。
accounts.google.com.conf:
此文件将是一个 JSON,它将覆盖一些 OIDC 选项。可以覆盖的选项列在 OpenID Connect Apache2 插件文档 中。
如果您不想覆盖配置值,可以将此文件保留为空 JSON,例如 {}。
accounts.google.com.provider:
此文件将包含有关 IdentityProvider 的所有规范。为了简化,您可以只使用在 .well-known 端点返回的 JSON
{
"issuer": "https://#",
"authorization_endpoint": "https://#/o/oauth2/v2/auth",
"token_endpoint": "https://oauth2.googleapis.com/token",
"userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
"revocation_endpoint": "https://oauth2.googleapis.com/revoke",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token",
"none"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"profile"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"iss",
"locale",
"name",
"picture",
"sub"
],
"code_challenge_methods_supported": [
"plain",
"S256"
]
}
继续配置 keystone¶
设置 Mellon¶
在继续这些 Mellon 特定说明之前,请参阅 Keystone 作为服务提供程序 (SP)。
配置 Apache HTTPD 以用于 mod_auth_mellon¶
注意
建议您仔细阅读 mod_auth_mellon 文档。
按照以下步骤操作:Keystone 安装指南中的 SUSE、RedHat 或 Ubuntu,配置 Apache http 服务器。
安装模块¶
安装 Apache 模块包。例如,在 Ubuntu 上
# apt-get install libapache2-mod-auth-mellon
软件包和模块名称因发行版而异。
配置 mod_auth_mellon¶
与 mod_shib 不同,mod_auth_mellon 的所有配置都在 Apache 中完成,而不是在单独的配置文件中。在 keystone VirtualHost 文件的顶部附近,在受保护的端点之前,设置一个共享设置在单个 <Location> 指令中
<Location /v3>
MellonEnable "info"
MellonSPPrivateKeyFile /etc/apache2/mellon/sp.keystone.example.org.key
MellonSPCertFile /etc/apache2/mellon/sp.keystone.example.org.cert
MellonSPMetadataFile /etc/apache2/mellon/sp-metadata.xml
MellonIdPMetadataFile /etc/apache2/mellon/idp-metadata.xml
MellonEndpointPath /v3/mellon
MellonIdP "IDP"
</Location>
配置受保护的端点¶
配置每个受保护的路径以使用 Mellon AuthType
<Location /v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth>
Require valid-user
AuthType Mellon
MellonEnable auth
</Location>
如果使用 horizon 作为单点登录前端,请对 WebSSO 身份验证路径执行相同的操作
<Location /v3/auth/OS-FEDERATION/websso/saml2>
Require valid-user
AuthType Mellon
MellonEnable auth
</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/samltest/protocols/saml2/websso>
Require valid-user
AuthType Mellon
MellonEnable auth
</Location>
配置 Mellon 服务提供程序元数据¶
Mellon 提供一个名为 mellon_create_metadata.sh``_ 的脚本,该脚本 生成 用于 config 指令 MellonSPPrivateKeyFile、MellonSPCertFile 和 MellonSPMetadataFile 的值。运行该脚本
$ ./mellon_create_metadata.sh \
https://sp.keystone.example.org/mellon \
http://sp.keystone.example.org/v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth/mellon
第一个参数用作实体 ID,一个您选择的 URN,必须唯一标识服务提供程序到身份提供程序。第二个参数是与参数 MellonEndpointPath 对应的端点路径的完整 URL。
生成密钥对和元数据后,将文件复制到 Apache 配置中 MellonSPPrivateKeyFile 和 MellonSPCertFile 设置中指定的位置。
将您刚刚生成的服务提供程序元数据文件上传到您的身份提供程序。这是用作配置中 MellonSPMetadataFile 的文件。IdP 可能会提供一个网页,您可以在其中上传该文件,或者您可能需要使用 wget 或 curl 提交该文件。请查阅您的 IdP 文档以获取详细信息。
交换元数据¶
获取您的身份提供程序的元数据文件并将其复制到 Apache 配置中 MellonIdPMetadataFile 设置中指定的路径。
$ wget -O /etc/apache2/mellon/idp-metadata.xml https://samltest.id/saml/idp
完成 Mellon 的配置后,请记住重新加载 Apache
# systemctl reload apache2
继续配置 keystone¶
设置 Shibboleth¶
在继续这些 Shibboleth 特定说明之前,请参阅 Keystone 作为服务提供程序 (SP)。
注意
以下示例适用于 Ubuntu 16.04,该版本仅提供 Shibboleth Service Provider 的版本 2。其他发行版提供版本 3,配置应与版本 2 相同。
配置 Apache HTTPD 以用于 mod_shib¶
注意
建议您仔细阅读 mod_shib Apache 配置文档。
按照 SUSE、RedHat 或 Ubuntu 的安装指南中的步骤,在 Apache 下配置 keystone。
安装模块¶
安装 Apache 模块包。例如,在 Ubuntu 上
# apt-get install libapache2-mod-shib2
软件包和模块名称因发行版而异。
配置受保护的端点¶
在 keystone VirtualHost 的 Apache 配置中,设置一个额外的 <Location>,该配置不是 keystone 的 API 的一部分
<Location /Shibboleth.sso>
SetHandler shib
</Location>
如果您正在使用 mod_proxy,例如将请求代理到 /identity 路径到 keystone 的 UWSGI 服务,则必须将此 Shibboleth 端点从其排除
Proxypass Shibboleth.sso !
配置每个受保护的路径以使用 shibboleth AuthType
<Location /v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth>
Require valid-user
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibExportAssertion off
<IfVersion < 2.4>
ShibRequireSession On
ShibRequireAll On
</IfVersion>
</Location>
如果使用 horizon 作为单点登录前端,请对 WebSSO 身份验证路径执行相同的操作
<Location /v3/auth/OS-FEDERATION/websso/saml2>
Require valid-user
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibExportAssertion off
<IfVersion < 2.4>
ShibRequireSession On
ShibRequireAll On
</IfVersion>
</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/samltest/protocols/saml2/websso>
Require valid-user
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibExportAssertion off
<IfVersion < 2.4>
ShibRequireSession On
ShibRequireAll On
</IfVersion>
</Location>
在更改 VirtualHost 后,请记住重新加载 Apache
# systemctl reload apache2
配置 mod_shib¶
注意
生成密钥对¶
对于所有 SAML 服务提供程序,必须生成一个 PKI 密钥对并与身份提供程序交换。Ubuntu 发行版上的 mod_shib 包提供了一个实用程序来生成密钥对
# shib-keygen -y <number of years>
这将生成 /etc/shibboleth 下的密钥对。在其他情况下,该包可能在安装时自动生成密钥对。
配置元数据¶
mod_shib 还在 /etc/shibboleth/shibboleth2.xml 中有一个自己的配置文件,必须对其进行更改,以及它自己的守护程序。首先,为服务提供程序提供一个实体 ID。这是一个您选择的 URN,必须对身份提供程序全局唯一
<ApplicationDefaults entityID="https://sp.keystone.example.org/shibboleth"
REMOTE_USER="eppn persistent-id targeted-id">
根据您的身份提供程序,您可能还需要更改 REMOTE_USER 设置,稍后会对此进行介绍。
设置身份提供程序的实体 ID(这与 Identity Provider 中提供的 --remote-id 值相同)
<SSO entityID="https://samltest.id/saml/idp">
此外,如果您想启用 ECP(对于 Keystone 到 Keystone 所需),则此实体的 SSO 标签也必须设置 ECP 标志
<SSO entityID="https://samltest.id/saml/idp" ECP="true">
告诉 Shibboleth 在哪里找到身份提供程序的元数据。您可以让它从 URI 获取它,也可以指向本地文件。例如,指向本地文件
<MetadataProvider type="XML" file="/etc/shibboleth/samltest-metadata.xml" />
或者指向远程位置
<MetadataProvider type="XML" url="https://samltest.id/saml/idp"
backingFile="samltest-metadata.xml" />
完成 shibboleth2.xml 的配置后,重新启动 shibd 守护程序
# systemctl restart shibd
检查 shibd 日志在 /var/log/shibboleth/shibd.log 和 /var/log/shibboleth/shibd_warn.log 中是否有错误或警告。
配置允许的属性¶
注意
有关更多信息,请参阅 属性文档
默认情况下,mod_shib 不会将从身份提供程序接收到的所有属性传递给 keystone。如果您的身份提供程序不使用 shibd 已知的属性,则必须配置它们。例如,samltest.id 使用自定义 UID 属性。它无法在身份提供程序元数据中发现,但属性名称和类型记录在身份验证尝试时 mod_shib 日志中。要允许该属性,请将其添加到 /etc/shibboleth/attribute-map.xml
<Attribute name="urn:oid:0.9.2342.19200300.100.1.1" id="uid" />
您可能还想将该属性用作 REMOTE_USER 变量的值,这将使 REMOTE_USER 变量可用作映射规则的参数。为此,将其添加到 /etc/shibboleth/shibboleth2.xml
<ApplicationDefaults entityID="https://sp.keystone.example.org/shibboleth"
REMOTE_USER="uid">
同样,如果使用 keystone 作为您的身份提供程序,则需要在 /etc/shibboleth/attribute-map.xml 中需要几个自定义属性
<Attribute name="openstack_user" id="openstack_user"/>
<Attribute name="openstack_roles" id="openstack_roles"/>
<Attribute name="openstack_project" id="openstack_project"/>
<Attribute name="openstack_user_domain" id="openstack_user_domain"/>
<Attribute name="openstack_project_domain" id="openstack_project_domain"/>
<Attribute name="openstack_groups" id="openstack_groups"/>
并更新 /etc/shibboleth/shibboleth2.xml 中的 REMOTE_USER 变量(如果需要)
<ApplicationDefaults entityID="https://sp.keystone.example.org/shibboleth"
REMOTE_USER="openstack_user">
在进行这些更改后,重新启动 shibd 守护程序
# systemctl restart shibd
交换元数据¶
配置完成后,服务提供商元数据即可下载
# wget https://sp.keystone.example.org/Shibboleth.sso/Metadata
将您的服务提供商的元数据上传到您的身份提供商。此步骤取决于您的身份提供商选择,此处不做介绍。如果 keystone 是您的身份提供商,则无需上传此文件。