13.3.9. 请求标头(Request header)
在 identityProviders
小节中设置 RequestHeaderIdentityProvider
,以标识请求标头值中的用户,如 X-Remote-User
。它通常与设定请求标头值的身份验证代理一起使用。这与 OpenShift Enterprise 2 中的远程用户插件 是,管理员可以提供 Kerberos、LDAP 和许多其他形式的企业身份验证。
您还可以将请求标头身份提供程序用于高级配置,如由社区支持的 SAML 身份验证。请注意,红帽不支持 SAML 验证。
要使用户使用这个身份提供程序进行身份验证,必须通过身份验证代理访问 https://<master>/oauth/authorize
(及子路径)。要达到此目的,请将 OAuth 服务器配置为将 OAuth 令牌的未经身份验证的请求重定向到代理到 https://<master>/oauth/authorize 的代理端点
。
重定向来自希望基于浏览器型登录流的客户端的未经身份验证请求:
-
将
login
参数设置为true
。 -
将
provider.loginURL
参数设置为身份验证代理 URL,该代理将验证交互式客户端并将其请求代理到https://<master>/oauth/authorize
。
重定向来自希望 WWW-Authenticate
质询的客户端的未经身份验证请求:
-
将
challenge
参数设置为true
。 -
将
provider.challengeURL
参数设置为身份验证代理 URL,该代理将验证希望WWW-Authenticate
质询的客户端,然后将请求代理到https://<master>/oauth/authorize
。
provider.challengeURL
和 provider.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
的 URL 必须以 /authorize 结尾(不含尾部斜杠),并代理子路径,以便 OAuth 批准流正常工作。/authorize
${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,但这种引用配置并不是必需的,且如果满足以下要求,您可以轻松地使用其他代理:
-
阻断来自客户端请求的
X-Remote-User
标头以防止欺骗。 -
在
RequestHeaderIdentityProvider
配置中强制进行客户端证书验证 。 -
使用质询流为所有身份验证请求设置
X-Csrf-Token
标头。 -
只有
/oauth/authorize
端点及其子路径应代理,并且不应重写重定向,从而使后端服务器可以将客户端发送到正确的位置。 代理到
https://<master>/oauth/authorize
的 URL 必须以/authorize
结尾(不含尾部斜杠)。例如:-
https://proxy.example.com/login-proxy/authorize?…
https://<master>/oauth/authorize?…
-
代理到
https://<master>/oauth/authorize
的 URL 的子路径必须代理到https://<master>/oauth/authorize 的
子路径。例如:-
https://proxy.example.com/login-proxy/authorize/approve?…
https://<master>/oauth/authorize/approve?…
-
安装先决条件
通过 Optional channel 获得 mod_auth_gssapi 模块。安装以下软件包:
# yum install -y httpd mod_ssl mod_session apr-util-openssl mod_auth_gssapi
生成用于验证提交可信标头的请求的 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。示例:为代理生成客户端证书这可以通过任何 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
注意oc adm create-api-client-config
命令生成有效期为两年的证书。这可以通过--expire-days
选项进行修改,但出于安全原因,建议不要超过这个值。仅从 Ansible 主机清单文件中列出的第一个 master 运行oc adm
命令,默认为 /etc/ansible/hosts。
配置 Apache
此代理不需要驻留在与 master 相同的主机上。它使用客户端证书连接到 master,该 master 配置为信任 X-Remote-User
标头。
-
为 Apache 配置创建证书。您通过
SSLProxyMachineCertificateFile
参数值指定的证书是用于向服务器验证代理的代理的客户端证书。它必须使用TLS Web 客户端身份验证
作为扩展密钥类型。 创建 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
验证配置
通过绕过代理来测试。如果您提供正确的客户端证书和标头,则可以请求令牌:
# curl -L -k -H "X-Remote-User: joe" \ --cert /etc/pki/tls/certs/authproxy.pem \ https://[MASTER]:8443/oauth/token/request
如果没有提供客户端证书,请求应该被拒绝:
# curl -L -k -H "X-Remote-User: joe" \ https://[MASTER]:8443/oauth/token/request
这应该会显示指向配置的
challengeURL
(带有额外查询参数)的重定向:# curl -k -v -H 'X-Csrf-Token: 1' \ '<masterPublicURL>/oauth/authorize?client_id=openshift-challenging-client&response_type=token'
这会显示带有
WWW-Authenticate
基本质询、协商质询或两个质询都有的 401 响应:# curl -k -v -H 'X-Csrf-Token: 1' \ '<redirected challengeURL from step 3 +query>'
测试在使用 Kerberos ticket 并不使用 Kerberos ticket 的情况下登录到
oc
命令行:如果您使用
kinit
生成了 Kerberos ticket,请将其销毁:# kdestroy -c cache_name 1
- 1
- 提供 Kerberos 缓存的名称。
使用您的 Kerberos 凭证登录到
oc
:# oc login
在提示符后输入您的 Kerberos 用户名和密码。
从
oc
命令行注销:# oc logout
使用您的 Kerberos 凭证获得一个 ticket:
# kinit
在提示符后输入您的 Kerberos 用户名和密码。
确认您可以登录到
oc
命令行:# oc login
如果配置正确,您会在不需要单独输入凭证的情况下成功登录。