搜索

13.3.9. 请求标头(Request header)

download PDF

identityProviders 小节中设置 RequestHeaderIdentityProvider,以标识请求标头值中的用户,如 X-Remote-User。它通常与设定请求标头值的身份验证代理一起使用。这与 OpenShift Enterprise 2 中的远程用户插件 是,管理员可以提供 Kerberos、LDAP 和许多其他形式的企业身份验证。

注意

您还可以将请求标头身份提供程序用于高级配置,如由社区支持的 SAML 身份验证。请注意,红帽不支持 SAML 验证。

要使用户使用这个身份提供程序进行身份验证,必须通过身份验证代理访问 https://<master>/oauth/authorize (及子路径)。要达到此目的,请将 OAuth 服务器配置为将 OAuth 令牌的未经身份验证的请求重定向到代理到 https://<master>/oauth/authorize 的代理端点

重定向来自希望基于浏览器型登录流的客户端的未经身份验证请求:

  1. login 参数设置为 true
  2. provider.loginURL 参数设置为身份验证代理 URL,该代理将验证交互式客户端并将其请求代理到 https://<master>/oauth/authorize

重定向来自希望 WWW-Authenticate 质询的客户端的未经身份验证请求:

  1. challenge 参数设置为 true
  2. provider.challengeURL 参数设置为身份验证代理 URL,该代理将验证希望 WWW-Authenticate 质询的客户端,然后将请求代理到 https://<master>/oauth/authorize

provider.challengeURLprovider.loginURL 参数可以在 URL 的查询部分中包含以下令牌:

  • ${url} 替换为当前的 URL,进行转义以在查询参数中安全使用。

    例如:https://www.example.com/sso-login?then=${url}

  • ${query} 替换为当前的查询字符串,不进行转义。

    例如:https://www.example.com/auth-proxy/oauth/authorize?${query}

警告

如果您期望未经身份验证的请求可以访问 OAuth 服务器,则需要为此此身份提供程序设置 clientCA 参数,以便在检查请求标头检查用户名的标头前检查传入的请求。否则,任何向 OAuth 服务器直接请求都可通过设置请求标头来模拟该提供程序的任何身份。

使用 RequestHeaderIdentityProvider 的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_request_header_provider 1
    challenge: true 2
    login: true 3
    mappingMethod: claim 4
    provider:
      apiVersion: v1
      kind: RequestHeaderIdentityProvider
      challengeURL: "https://www.example.com/challenging-proxy/oauth/authorize?${query}" 5
      loginURL: "https://www.example.com/login-proxy/oauth/authorize?${query}" 6
      clientCA: /path/to/client-ca.file 7
      clientCommonNames: 8
      - my-auth-proxy
      headers: 9
      - X-Remote-User
      - SSO-User
      emailHeaders: 10
      - X-Remote-User-Email
      nameHeaders: 11
      - X-Remote-User-Display-Name
      preferredUsernameHeaders: 12
      - X-Remote-User-Login

1
此提供程序名称作为前缀放在请求标头中的用户名前,以此组成身份名称。
2
RequestHeaderIdentityProvider 只能通过重定向到配置的 challengeURL 来响应请求 WWW-Authenticate 质询的客户端。配置的 URL 应以 WWW-Authenticate 质询进行响应。
3
RequestHeaderIdentityProvider 只能通过重定向到配置的 loginURL来响应请求登录流的客户端。配置的 URL 应通过登录流做出响应。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
可选:将未经身份验证的 /oauth/authorize 请求重定向到的 URL,该请求将验证希望 WWW-Authenticate 质询的客户端,然后将它们代理到 https://<master>/oauth/authorize. ${url} 替换为当前的 URL,进行转义以在查询参数中安全使用。${query} 替换为当前的查询字符串。
6
可选:将未经身份验证的 /oauth/authorize 请求重定向到的 URL,它将验证基于浏览器的客户端,然后将请求代理到 https://<master>/oauth/authorize。代理到 https://<master>/oauth /authorize 的 URL 必须以 /authorize 结尾(不含尾部斜杠),并代理子路径,以便 OAuth 批准流正常工作。${url} 替换为当前的 URL,进行转义以在查询参数中安全使用。${query} 替换为当前的查询字符串。
7
可选:PEM 编码的证书捆绑包。如果设置,则必须根据指定文件中的证书颁发机构显示并验证有效的客户端证书,然后才能检查请求标头中的用户名。
8
可选:通用名称 (cn) 的列表。如果设定,则必须出示带有指定列表中通用名称 (cn) 的有效客户端证书,然后才能检查请求标头中的用户名。如果为空,则允许任何通用名称。只能与 clientCA 结合使用。
9
按顺序查找用户身份的标头名称。第一个包含值的标头被用作身份。必需,不区分大小写。
10
按顺序查找电子邮件地址的标头名称。第一个包含值的标头被用作电子邮件地址。可选,不区分大小写。
11
按顺序查找显示名称的标头名称。第一个包含值的标头被用作显示名称。可选,不区分大小写。
12
按顺序查找首选用户名的标头名称(如果与通过 headers 中指定的标头确定的不可变身份不同)。在置备时,第一个包含值的标头用作首选用户名。可选,不区分大小写。
Microsoft Windows 上的 SSPI 连接支持
重要

使用 Microsoft Windows 上的 SSPI 连接支持是技术预览功能。技术预览功能不包括在红帽生产服务级别协议(SLA)中,且其功能可能并不完善。因此,红帽不建议在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

如需红帽技术预览功能支持范围的更多信息,请参阅 https://access.redhat.com/support/offerings/techpreview/

从版本 3.11 开始,

oc 支持安全支持提供程序接口 (SSPI),以允许 Microsft Windows 上的 SSO 流。如果您使用请求标头身份提供程序与支持 GSSAPI 的代理将 Active Directory 服务器连接到 OpenShift Container Platform,用户可以通过加入了域的 Microsoft Windows 计算机使用 oc 命令行界面来自动进行 OpenShift Container Platform 身份验证。

使用 Request 标头的 Apache 身份验证

本例在与 master 位于同一主机上配置身份验证代理。在同一主机上让代理和 master 提供方便方便的,可能不适用于您的环境。例如,如果您已在 master 上运行 路由器,端口 443 不可用。

另请务必注意,尽管此参考配置使用 Apache 的 mod_auth_gssapi,但这种引用配置并不是必需的,且如果满足以下要求,您可以轻松地使用其他代理:

  1. 阻断来自客户端请求的 X-Remote-User 标头以防止欺骗。
  2. RequestHeaderIdentityProvider 配置中强制进行客户端证书验证 。
  3. 使用质询流为所有身份验证请求设置 X-Csrf-Token 标头。
  4. 只有 /oauth/authorize 端点及其子路径应代理,并且不应重写重定向,从而使后端服务器可以将客户端发送到正确的位置。
  5. 代理到 https://<master>/oauth/authorize 的 URL 必须以 /authorize 结尾(不含尾部斜杠)。例如:

    • https://proxy.example.com/login-proxy/authorize?…​ https://<master>/oauth/authorize?…​
  6. 代理到 https://<master>/oauth/authorize 的 URL 的子路径必须代理到 https://<master>/oauth/authorize 的 子路径。例如:

    • https://proxy.example.com/login-proxy/authorize/approve?…​ https://<master>/oauth/authorize/approve?…​
安装先决条件
  1. 通过 Optional channel 获得 mod_auth_gssapi 模块。安装以下软件包:

    # yum install -y httpd mod_ssl mod_session apr-util-openssl mod_auth_gssapi
  2. 生成用于验证提交可信标头的请求的 CA。此 CA 应在 master 身份提供程序配置中用作 clientCA 的文件名。

    # oc adm ca create-signer-cert \
      --cert='/etc/origin/master/proxyca.crt' \
      --key='/etc/origin/master/proxyca.key' \
      --name='openshift-proxy-signer@1432232228' \
      --serial='/etc/origin/master/proxyca.serial.txt'
    注意

    oc adm ca create-signer-cert 命令生成有效 5 年的证书。这可以通过 --expire-days 选项进行修改,但出于安全原因,建议不要超过这个值。

    仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

  3. 示例:为代理生成客户端证书这可以通过任何 x509 证书工具完成。为方便起见,可以使用 oc adm CLI:

    # oc adm create-api-client-config \
      --certificate-authority='/etc/origin/master/proxyca.crt' \
      --client-dir='/etc/origin/master/proxy' \
      --signer-cert='/etc/origin/master/proxyca.crt' \
      --signer-key='/etc/origin/master/proxyca.key' \
      --signer-serial='/etc/origin/master/proxyca.serial.txt' \
      --user='system:proxy' 1
    
    # pushd /etc/origin/master
    # cp master.server.crt /etc/pki/tls/certs/localhost.crt 2
    # cp master.server.key /etc/pki/tls/private/localhost.key
    # cp ca.crt /etc/pki/CA/certs/ca.crt
    # cat proxy/system\:proxy.crt \
      proxy/system\:proxy.key > \
      /etc/pki/tls/certs/authproxy.pem
    # popd
    1
    用户名可以是任何内容,但为它赋予一个描述性名称,因为它将在日志中出现时很有用。
    2
    在与 master 不同的主机名中运行身份验证代理时,生成与主机名匹配的证书非常重要,而不必使用如上所示的默认 master 证书。/etc/origin/master/master-config.yaml 文件中的 masterPublicURL 的值需要包括在为 SSLCertificateFile 指定的证书的 X509v3 Subject Alternative Name 中。如果需要创建新证书,可以使用 oc adm ca create-server-cert 命令。
    注意

    oc adm create-api-client-config 命令生成有效期为两年的证书。这可以通过 --expire-days 选项进行修改,但出于安全原因,建议不要超过这个值。仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

配置 Apache

此代理不需要驻留在与 master 相同的主机上。它使用客户端证书连接到 master,该 master 配置为信任 X-Remote-User 标头。

  1. 为 Apache 配置创建证书。您通过 SSLProxyMachineCertificateFile 参数值指定的证书是用于向服务器验证代理的代理的客户端证书。它必须使用 TLS Web 客户端身份验证作为扩展密钥类型。
  2. 创建 Apache 配置文件。使用以下模板来提供所需设置和值:

    重要

    仔细检查模板的内容,并根据您的环境自定义其相应的内容。

    LoadModule request_module modules/mod_request.so
    LoadModule auth_gssapi_module modules/mod_auth_gssapi.so
    # Some Apache configurations might require these modules.
    # LoadModule auth_form_module modules/mod_auth_form.so
    # LoadModule session_module modules/mod_session.so
    
    # Nothing needs to be served over HTTP.  This virtual host simply redirects to
    # HTTPS.
    <VirtualHost *:80>
      DocumentRoot /var/www/html
      RewriteEngine              On
      RewriteRule     ^(.*)$     https://%{HTTP_HOST}$1 [R,L]
    </VirtualHost>
    
    <VirtualHost *:443>
      # This needs to match the certificates you generated.  See the CN and X509v3
      # Subject Alternative Name in the output of:
      # openssl x509 -text -in /etc/pki/tls/certs/localhost.crt
      ServerName www.example.com
    
      DocumentRoot /var/www/html
      SSLEngine on
      SSLCertificateFile /etc/pki/tls/certs/localhost.crt
      SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
      SSLCACertificateFile /etc/pki/CA/certs/ca.crt
    
      SSLProxyEngine on
      SSLProxyCACertificateFile /etc/pki/CA/certs/ca.crt
      # It's critical to enforce client certificates on the Master.  Otherwise
      # requests could spoof the X-Remote-User header by accessing the Master's
      # /oauth/authorize endpoint directly.
      SSLProxyMachineCertificateFile /etc/pki/tls/certs/authproxy.pem
    
      # Send all requests to the console
      RewriteEngine              On
      RewriteRule     ^/console(.*)$     https://%{HTTP_HOST}:8443/console$1 [R,L]
    
      # In order to using the challenging-proxy an X-Csrf-Token must be present.
      RewriteCond %{REQUEST_URI} ^/challenging-proxy
      RewriteCond %{HTTP:X-Csrf-Token} ^$ [NC]
      RewriteRule ^.* - [F,L]
    
      <Location /challenging-proxy/oauth/authorize>
          # Insert your backend server name/ip here.
          ProxyPass https://[MASTER]:8443/oauth/authorize
          AuthName "SSO Login"
          # For Kerberos
          AuthType GSSAPI
          Require valid-user
          RequestHeader set X-Remote-User %{REMOTE_USER}s
    
          GssapiCredStore keytab:/etc/httpd/protected/auth-proxy.keytab
          # Enable the following if you want to allow users to fallback
          # to password based authntication when they do not have a client
          # configured to perform kerberos authentication
          GssapiBasicAuth On
    
          # For ldap:
          # AuthBasicProvider ldap
          # AuthLDAPURL "ldap://ldap.example.com:389/ou=People,dc=my-domain,dc=com?uid?sub?(objectClass=*)"
    
          # It's possible to remove the mod_auth_gssapi usage and replace it with
          # something like mod_auth_mellon, which only supports the login flow.
        </Location>
    
        <Location /login-proxy/oauth/authorize>
        # Insert your backend server name/ip here.
        ProxyPass https://[MASTER]:8443/oauth/authorize
    
          AuthName "SSO Login"
          AuthType GSSAPI
          Require valid-user
          RequestHeader set X-Remote-User %{REMOTE_USER}s env=REMOTE_USER
    
          GssapiCredStore keytab:/etc/httpd/protected/auth-proxy.keytab
          # Enable the following if you want to allow users to fallback
          # to password based authntication when they do not have a client
          # configured to perform kerberos authentication
          GssapiBasicAuth On
    
          ErrorDocument 401 /login.html
        </Location>
    
    </VirtualHost>
    
    RequestHeader unset X-Remote-User
配置 master

/etc/origin/master/master-config.yaml 文件中的 identityProviders 小节必须更新:

  identityProviders:
  - name: requestheader
    challenge: true
    login: true
    provider:
      apiVersion: v1
      kind: RequestHeaderIdentityProvider
      challengeURL: "https://[MASTER]/challenging-proxy/oauth/authorize?${query}"
      loginURL: "https://[MASTER]/login-proxy/oauth/authorize?${query}"
      clientCA: /etc/origin/master/proxyca.crt
      headers:
      - X-Remote-User
重启服务

最后,重启以下服务:

# systemctl restart httpd
# master-restart api
# master-restart controllers
验证配置
  1. 通过绕过代理来测试。如果您提供正确的客户端证书和标头,则可以请求令牌:

    # curl -L -k -H "X-Remote-User: joe" \
       --cert /etc/pki/tls/certs/authproxy.pem \
       https://[MASTER]:8443/oauth/token/request
  2. 如果没有提供客户端证书,请求应该被拒绝:

    # curl -L -k -H "X-Remote-User: joe" \
       https://[MASTER]:8443/oauth/token/request
  3. 这应该会显示指向配置的 challengeURL (带有额外查询参数)的重定向:

    # curl -k -v -H 'X-Csrf-Token: 1' \
       '<masterPublicURL>/oauth/authorize?client_id=openshift-challenging-client&response_type=token'
  4. 这会显示带有 WWW-Authenticate 基本质询、协商质询或两个质询都有的 401 响应:

    #  curl -k -v -H 'X-Csrf-Token: 1' \
        '<redirected challengeURL from step 3 +query>'
  5. 测试在使用 Kerberos ticket 并不使用 Kerberos ticket 的情况下登录到 oc 命令行:

    1. 如果您使用 kinit生成了 Kerberos ticket,请将其销毁:

      # kdestroy -c cache_name 1
      1
      提供 Kerberos 缓存的名称。
    2. 使用您的 Kerberos 凭证登录到 oc

      # oc login

      在提示符后输入您的 Kerberos 用户名和密码。

    3. oc 命令行注销:

      # oc logout
    4. 使用您的 Kerberos 凭证获得一个 ticket:

      # kinit

      在提示符后输入您的 Kerberos 用户名和密码。

    5. 确认您可以登录到 oc 命令行:

      # oc login

      如果配置正确,您会在不需要单独输入凭证的情况下成功登录。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.