第 9 章 在 RHOSO 中配置多域联邦身份验证


您可以在 OpenShift (RHOSO) Identity 服务(keystone)和 Dashboard (horizon)上配置 Red Hat OpenStack Services,以使用 OpenID Connect (OIDC)作为协议来提供多域联邦身份验证。多域联邦允许用户使用单点登录(SSO)登录 OpenStack 控制面板,并从多个外部身份提供程序(IdP)之一中进行选择。

9.1. 使用多个联邦身份提供程序部署 RHOSO

多域联邦允许用户使用单点登录(SSO)登录 OpenShift (RHOSO) Dashboard 上的 Red Hat OpenStack Services,并从多个外部身份提供程序(IdP)中选择。

注意

多个联邦 IdP 的 RHOSO 部署实施 Web SSO 身份验证流,因为 OpenStack CLI 不支持多个 IdP。

先决条件

  • 已安装 RHOSO。
  • 您在您的环境中配置了多个外部 OpenID Connect (OIDC) IdP。

流程

  1. 选择一个名称来唯一标识每个 IdP。

    在这个示例中,有两个 IdP,它们的名称被引用为 < idp_name_1> 和 < idp_name_2>

  2. 从每个 IdP 管理员获取以下设置:

    • 此流程中引用的每个 IdP 的 FQDN 作为 < fqdn_1> 和 &lt; fqdn_2>
    • 此流程中引用的每个 IdP 的 federation Realm Name 作为 < realm_name_1> 和 &lt; realm_name_2>
    • 此流程中引用的每个 IdP 的客户端 ID 作为 < client_id_1> 和 < client_id_2>
    • 此流程中引用的每个 IdP 的客户端 Secret,作为 < client_secret_1> 和 &lt; client_secret_2>
    • 此流程中引用的每个 IdP 的 Provider Metadata URL 作为 < provider_metadata_url_1> 和 &lt; provider_metadata_url_2>
  3. 检索 Identity 服务(keystone)公共端点:

    $ oc get keystoneapis.keystone.openstack.org -o json | jq '.items[0].status.apiEndpoints.public'

    此流程中将这个身份服务端点引用为 < keystone_url >。

  4. 为 IdP 管理员提供以下信息:

    • Web origin:

      https://<keystone_url>
    • 重定向 URI:

      https://<keystone_url>/v3/auth/OS-FEDERATION/websso/openid

      为每个 IdP 提供包含其唯一 IdP 名称的 URI,该名称必须以尾随 / 结尾。您必须将每个 URI 发送到其对应的 IdP 管理员:

      https://<keystone_url>/v3/auth/OS-FEDERATION/identity_providers/<idp_name_1>/protocols/openid/websso/
      https://<keystone_url>/v3/auth/OS-FEDERATION/identity_providers/<idp_name_2>/protocols/openid/websso/
    • 每个联邦客户端都必须启用 Implicit 流,而不是授权代码流。
  5. 为名为 keystone-httpd-override 的 secret 创建自定义资源(CR)文件:

    apiVersion: v1
    kind: Secret
    metadata:
     name: keystone-httpd-override
     namespace: openstack
    type: Opaque
    stringData:
     federation.conf: |
       # Example OIDC directives for the *public* endpoint
       OIDCClaimPrefix "OIDC-"
       OIDCResponseType "id_token"
       OIDCScope "openid email profile"
       OIDCClaimDelimiter ";"
       OIDCPassUserInfoAs "claims"
       OIDCPassClaimsAs "both"
       OIDCCryptoPassphrase "<crypto_pass>"
       OIDCRedirectURI "<keystone_url>/v3/redirect_uri/"
                            OIDCMetadataDir "/var/lib/httpd/metadata"
       OIDCAuthRequestParams "prompt=login"
       <IfModule headers_module>
         <Location "/v3/local-logout/clear">
           Header always add Set-Cookie "mod_auth_openidc_session=deleted; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=None"
         </Location>
       </IfModule>
    
       RewriteEngine On
    
       RewriteRule ^/v3/auth/OS-FEDERATION/identity_providers/(<idp_name_1>|<idp_name_2>)/protocols/openid/websso$ \
         /v3/local-logout/clear [R=302,L]
    
       RewriteRule ^/v3/local-logout/clear$ \
         /v3/auth/OS-FEDERATION/websso/openid [R=302,L,QSA,NE]
    
       <Location "/v3/auth/OS-FEDERATION/websso/openid">
         AuthType openid-connect
         Require  valid-user
       </Location>
    
       <Location "/v3/redirect_uri">
         AuthType openid-connect
         Require  valid-user
       </Location>
    重要

    OIDCRedirectURI 参数的完整值必须以尾随 / 结尾。

    • <crypto_pass > 替换为在加密 OpenID Connect 握手数据时要使用的用户定义的密码短语。
    • <keystone_url > 替换为在第 3 步中获取的 Identity 服务端点值。
    • <idp_name_1& gt ; 和 <idp_name_ 2> 替换为在第 1 步中指定的唯一 IdP 名称。
    • 以下 OIDC 参数和相关 Apache 配置旨在提供支持多个 IdP 登录用户的最故障安全解决方案。因此,以前的会话不会被保存,用户必须在从仪表板注销后重新验证自己:

       OIDCAuthRequestParams "prompt=login"
      
      
       <IfModule headers_module>
         <Location "/v3/local-logout/clear">
           Header always add Set-Cookie "mod_auth_openidc_session=deleted; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=None"
         </Location>
       </IfModule>
        RewriteEngine On
        RewriteRule ^/v3/auth/OS-FEDERATION/identity_providers/(<idp_name_1>|<idp_name_2>)/protocols/openid/websso$ \
         /v3/local-logout/clear [R=302,L]
        RewriteRule ^/v3/local-logout/clear$ \
         /v3/auth/OS-FEDERATION/websso/openid [R=302,L,QSA,NE]

      如果您的多个联邦 IdP 部署中的用户不属于多个 IdP,则您可以允许用户重新打开仪表板,而无需提供任何身份验证。在这种情况下,您必须删除此 OIDC 参数,并提供不同的 Apache LocationMatch 配置来保存之前的会话。

  6. 创建 keystone-httpd-override secret:

    $ oc create -f keystone-httpd-override.yaml
  7. 检索仪表板的 URL:

    $ oc get horizons.horizon.openstack.org -o json | jq -r '.items[0].status.endpoint'
  8. 使用以下 Ansible playbook 创建名为 federation-realm-data 的 secret:

    - name: Download realm1 OpenID configuration
      ansible.builtin.uri:
        url: "<provider_metadata_url_1>"
        method: GET
        return_content: true
        validate_certs: false
      register: openid_wellknown_config1
    
    
    - name: Download realm2 OpenID configuration
      ansible.builtin.uri:
        url: "<provider_metadata_url_2>"
        method: GET
        return_content: true
        validate_certs: false
      register: openid_wellknown_config2
    
    
    - name: Set federation_config_items
      ansible.builtin.set_fact:
        federation_config_items:
          - filename: "<fqdn_1>%2Fauth%2Frealms%2F<realm_name_1>.conf"
            contents: |
              {
                "scope" : "openid email profile"
              }
          - filename: "<fqdn_1>%2Fauth%2Frealms%2F<realm_name_1>.client"
            contents: "{{ {'client_id': <client_id_1>, 'client_secret': <client_secret_1> } | to_json }}"
          - filename: "<fqdn_1>%2Fauth%2Frealms%2F<realm_name_1>.provider"
            contents: |
              {{ openid_wellknown_config1.content }}
          - filename: "<fqdn_2>%2Fauth%2Frealms%2F<realm_name_2>.conf"
            contents: |
              {
                "scope" : "openid email profile"
              }
          - filename: "<fqdn_2>%2Fauth%2Frealms%2F<realm_name_2>.client"
            contents: "{{ {'client_id': <client_id_2>, 'client_secret': <client_secret_2>} | to_json }}"
          - filename: "<fqdn_2>%2Fauth%2Frealms%2F<realm_name_2>.provider"
            contents: |
              {{ openid_wellknown_config2.content }}
    - name: Generate the final federation_config.json string (as a dictionary)
      ansible.builtin.set_fact:
        _raw_federation_config_json_value: |
          {
          {% for item in federation_config_items %}
            "{{ item.filename }}": {{ item.contents }}{% if not loop.last %},{% endif %}
          {% endfor %}
          }
    - name: Final JSON string for Secret stringData
      ansible.builtin.set_fact:
        federation_config_json_string: "{{ _raw_federation_config_json_value }}"
    
    
    - name: Create a Kubernetes Secret with federation metadata
      kubernetes.core.k8s:
        state: present
        definition:
          apiVersion: v1
          kind: Secret
          type: Opaque
          metadata:
            name: federation-realm-data
            namespace: openstack
          stringData:
            federation-config.json: "{{ federation_config_json_string }}"
    • 将 IdP 变量替换为在第 2 步中从 IdP 管理员获取的值。
  9. 在工作站上打开 OpenStackControlPlane 自定义资源(CR)文件 openstack_control_plane.yaml
  10. 编辑 OpenStackControlPlane CR 的 keystone 部分:

    keystone:
     template:
       customServiceConfig: |
         [federation]
         trusted_dashboard=<horizon_endpoint>/dashboard/auth/websso/
         [openid]
         remote_id_attribute=HTTP_OIDC_ISS
         [auth]
         methods = password,token,oauth1,mapped,application_credential,openid
       httpdCustomization:
         customConfigSecret: keystone-httpd-override
         federatedRealmConfig: federation-realm-data
    • <horizon_endpoint > 替换为在第 7 步中获取的 Dashboard URL。
    • 方法 = 分隔列表中删除 外部
    • httpdCustomization 下添加 customConfigSecret 参数,并将此值设置为在第 5 步中 keystone-httpd-override.yaml CR 文件中创建的键。
    • 添加 federatedRealmConfig 参数,并将此值设置为第 8 步中 Ansible Playbook 创建的 federation-realm-data secret。
  11. 编辑 OpenStackControlPlane CR 的 horizon 部分:

    horizon:
     template:
     customServiceConfig: |
       # Point horizon to the keystone public endpoint
       OPENSTACK_KEYSTONE_URL = "<keystone_endpoint>/v3"
    
    
       # Enable WebSSO in horizon
       WEBSSO_ENABLED = True
    
    
       # Provide login options in the horizon dropdown menu
       WEBSSO_CHOICES = (
         ("credentials", _("Keystone Credentials")),
         ("OIDC1", _("OpenID Connect IdP1")),
         ("OIDC2", _("OpenID Connect IdP2")),
       )
    
    
       # Map the "OIDC" choice of horizon to the keystone IDP and protocol
       WEBSSO_IDP_MAPPING = {
         "OIDC1": ("<idp_name1>", "openid"),
         "OIDC2": ("<idp_name2>", "openid"),
       }
  12. 更新 control plane:

    $ oc apply -f openstack_control_plane.yaml -n openstack
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat
返回顶部