Configuring a request header identity provider

Configure a request-header identity provider to identify users from request header values, such as X-Remote-User. It is typically used in combination with an authenticating proxy, which sets the request header value.

About identity providers in OKD

By default, only a kubeadmin user exists on your cluster. To specify an identity provider, you must create a custom resource (CR) that describes that identity provider and add it to the cluster.

OKD user names containing /, :, and % are not supported.

About request header authentication

A request header identity provider identifies users from request header values, such as X-Remote-User. It is typically used in combination with an authenticating proxy, which sets the request header value. The request header identity provider cannot be combined with other identity providers that use direct password logins, such as HTPasswd, Keystone, LDAP or Basic authentication.

You can also use the request header identity provider for advanced configurations such as the community-supported SAML authentication. Note that this solution is not supported by Red Hat.

For users to authenticate using this identity provider, they must access https://*<namespace_route>*/oauth/authorize (and subpaths) via an authenticating proxy. To accomplish this, configure the OAuth server to redirect unauthenticated requests for OAuth tokens to the proxy endpoint that proxies to https://*<namespace_route>*/oauth/authorize.

To redirect unauthenticated requests from clients expecting browser-based login flows:

  • Set the provider.loginURL parameter to the authenticating proxy URL that will authenticate interactive clients and then proxy the request to https://*<namespace_route>*/oauth/authorize.

To redirect unauthenticated requests from clients expecting WWW-Authenticate challenges:

  • Set the provider.challengeURL parameter to the authenticating proxy URL that will authenticate clients expecting WWW-Authenticate challenges and then proxy the request to https://*<namespace_route>*/oauth/authorize.

The provider.challengeURL and provider.loginURL parameters can include the following tokens in the query portion of the URL:

  • ${url} is replaced with the current URL, escaped to be safe in a query parameter.

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

  • ${query} is replaced with the current query string, unescaped.

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

As of OKD 4.1, your proxy must support mutual TLS.

SSPI connection support on Microsoft Windows

The OpenShift CLI (oc) supports the Security Support Provider Interface (SSPI) to allow for SSO flows on Microsft Windows. If you use the request header identity provider with a GSSAPI-enabled proxy to connect an Active Directory server to OKD, users can automatically authenticate to OKD by using the oc command line interface from a domain-joined Microsoft Windows computer.

Creating a config map

Identity providers use OKD ConfigMap objects in the openshift-config namespace to contain the certificate authority bundle. These are primarily used to contain certificate bundles needed by the identity provider.

Procedure

  • Define an OKD ConfigMap object containing the certificate authority by using the following command. The certificate authority must be stored in the ca.crt key of the ConfigMap object.

    1. $ oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config

    You can alternatively apply the following YAML to create the config map:

    1. apiVersion: v1
    2. kind: ConfigMap
    3. metadata:
    4. name: ca-config-map
    5. namespace: openshift-config
    6. data:
    7. ca.crt: |
    8. <CA_certificate_PEM>

Sample request header CR

The following custom resource (CR) shows the parameters and acceptable values for a request header identity provider.

Request header CR

  1. apiVersion: config.openshift.io/v1
  2. kind: OAuth
  3. metadata:
  4. name: cluster
  5. spec:
  6. identityProviders:
  7. - name: requestheaderidp (1)
  8. mappingMethod: claim (2)
  9. type: RequestHeader
  10. requestHeader:
  11. challengeURL: "https://www.example.com/challenging-proxy/oauth/authorize?${query}" (3)
  12. loginURL: "https://www.example.com/login-proxy/oauth/authorize?${query}" (4)
  13. ca: (5)
  14. name: ca-config-map
  15. clientCommonNames: (6)
  16. - my-auth-proxy
  17. headers: (7)
  18. - X-Remote-User
  19. - SSO-User
  20. emailHeaders: (8)
  21. - X-Remote-User-Email
  22. nameHeaders: (9)
  23. - X-Remote-User-Display-Name
  24. preferredUsernameHeaders: (10)
  25. - X-Remote-User-Login
1This provider name is prefixed to the user name in the request header to form an identity name.
2Controls how mappings are established between this provider’s identities and User objects.
3Optional: URL to redirect unauthenticated /oauth/authorize requests to, that will authenticate browser-based clients and then proxy their request to https://<namespace_route>/oauth/authorize. The URL that proxies to https://<namespace_route>/oauth/authorize must end with /authorize (with no trailing slash), and also proxy subpaths, in order for OAuth approval flows to work properly. ${url} is replaced with the current URL, escaped to be safe in a query parameter. ${query} is replaced with the current query string. If this attribute is not defined, then loginURL must be used.
4Optional: URL to redirect unauthenticated /oauth/authorize requests to, that will authenticate clients which expect WWW-Authenticate challenges, and then proxy them to https://<namespace_route>/oauth/authorize. ${url} is replaced with the current URL, escaped to be safe in a query parameter. ${query} is replaced with the current query string. If this attribute is not defined, then challengeURL must be used.
5Reference to an OKD ConfigMap object containing a PEM-encoded certificate bundle. Used as a trust anchor to validate the TLS certificates presented by the remote server.

As of OKD 4.1, the ca field is required for this identity provider. This means that your proxy must support mutual TLS.

6Optional: list of common names (cn). If set, a valid client certificate with a Common Name (cn) in the specified list must be presented before the request headers are checked for user names. If empty, any Common Name is allowed. Can only be used in combination with ca.
7Header names to check, in order, for the user identity. The first header containing a value is used as the identity. Required, case-insensitive.
8Header names to check, in order, for an email address. The first header containing a value is used as the email address. Optional, case-insensitive.
9Header names to check, in order, for a display name. The first header containing a value is used as the display name. Optional, case-insensitive.
10Header names to check, in order, for a preferred user name, if different than the immutable identity determined from the headers specified in headers. The first header containing a value is used as the preferred user name when provisioning. Optional, case-insensitive.

Additional resources

Adding an identity provider to your clusters

After you install your cluster, add an identity provider to it so your users can authenticate.

Prerequisites

  • Create an OKD cluster.

  • Create the custom resource (CR) for your identity providers.

  • You must be logged in as an administrator.

Procedure

  1. Apply the defined CR:

    1. $ oc apply -f </path/to/CR>

    If a CR does not exist, oc apply creates a new CR and might trigger the following warning: Warning: oc apply should be used on resources created by either oc create —save-config or oc apply. In this case you can safely ignore this warning.

  2. Log in to the cluster as a user from your identity provider, entering the password when prompted.

    1. $ oc login -u <username>
  3. Confirm that the user logged in successfully, and display the user name.

    1. $ oc whoami

Example Apache authentication configuration using request header

This example configures an Apache authentication proxy for the OKD using the request header identity provider.

Custom proxy configuration

Using the mod_auth_gssapi module is a popular way to configure the Apache authentication proxy using the request header identity provider; however, it is not required. Other proxies can easily be used if the following requirements are met:

  • Block the X-Remote-User header from client requests to prevent spoofing.

  • Enforce client certificate authentication in the RequestHeaderIdentityProvider configuration.

  • Require the X-Csrf-Token header be set for all authentication requests using the challenge flow.

  • Make sure only the /oauth/authorize endpoint and its subpaths are proxied; redirects must be rewritten to allow the backend server to send the client to the correct location.

  • The URL that proxies to https://<namespace_route>/oauth/authorize must end with /authorize with no trailing slash. For example, https://proxy.example.com/login-proxy/authorize?…​ must proxy to https://<namespace_route>/oauth/authorize?…​.

  • Subpaths of the URL that proxies to https://<namespace_route>/oauth/authorize must proxy to subpaths of https://<namespace_route>/oauth/authorize. For example, https://proxy.example.com/login-proxy/authorize/approve?…​ must proxy to https://<namespace_route>/oauth/authorize/approve?…​.

The https://<namespace_route&gt; address is the route to the OAuth server and can be obtained by running oc get route -n openshift-authentication.

Configuring Apache authentication using request header

This example uses the mod_auth_gssapi module to configure an Apache authentication proxy using the request header identity provider.

Prerequisites

  • Obtain the mod_auth_gssapi module from the Optional channel. You must have the following packages installed on your local machine:

    • httpd

    • mod_ssl

    • mod_session

    • apr-util-openssl

    • mod_auth_gssapi

  • Generate a CA for validating requests that submit the trusted header. Define an OKD ConfigMap object containing the CA. This is done by running:

    1. $ oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config (1)
    1The CA must be stored in the ca.crt key of the ConfigMap object.

    You can alternatively apply the following YAML to create the config map:

    1. apiVersion: v1
    2. kind: ConfigMap
    3. metadata:
    4. name: ca-config-map
    5. namespace: openshift-config
    6. data:
    7. ca.crt: |
    8. <CA_certificate_PEM>
  • Generate a client certificate for the proxy. You can generate this certificate by using any x509 certificate tooling. The client certificate must be signed by the CA you generated for validating requests that submit the trusted header.

  • Create the custom resource (CR) for your identity providers.

Procedure

This proxy uses a client certificate to connect to the OAuth server, which is configured to trust the X-Remote-User header.

  1. Create the certificate for the Apache configuration. The certificate that you specify as the SSLProxyMachineCertificateFile parameter value is the proxy’s client certificate that is used to authenticate the proxy to the server. It must use TLS Web Client Authentication as the extended key type.

  2. Create the Apache configuration. Use the following template to provide your required settings and values:

    Carefully review the template and customize its contents to fit your environment.

    1. LoadModule request_module modules/mod_request.so
    2. LoadModule auth_gssapi_module modules/mod_auth_gssapi.so
    3. # Some Apache configurations might require these modules.
    4. # LoadModule auth_form_module modules/mod_auth_form.so
    5. # LoadModule session_module modules/mod_session.so
    6. # Nothing needs to be served over HTTP. This virtual host simply redirects to
    7. # HTTPS.
    8. <VirtualHost *:80>
    9. DocumentRoot /var/www/html
    10. RewriteEngine On
    11. RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
    12. </VirtualHost>
    13. <VirtualHost *:443>
    14. # This needs to match the certificates you generated. See the CN and X509v3
    15. # Subject Alternative Name in the output of:
    16. # openssl x509 -text -in /etc/pki/tls/certs/localhost.crt
    17. ServerName www.example.com
    18. DocumentRoot /var/www/html
    19. SSLEngine on
    20. SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    21. SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    22. SSLCACertificateFile /etc/pki/CA/certs/ca.crt
    23. SSLProxyEngine on
    24. SSLProxyCACertificateFile /etc/pki/CA/certs/ca.crt
    25. # It is critical to enforce client certificates. Otherwise, requests can
    26. # spoof the X-Remote-User header by accessing the /oauth/authorize endpoint
    27. # directly.
    28. SSLProxyMachineCertificateFile /etc/pki/tls/certs/authproxy.pem
    29. # To use the challenging-proxy, an X-Csrf-Token must be present.
    30. RewriteCond %{REQUEST_URI} ^/challenging-proxy
    31. RewriteCond %{HTTP:X-Csrf-Token} ^$ [NC]
    32. RewriteRule ^.* - [F,L]
    33. <Location /challenging-proxy/oauth/authorize>
    34. # Insert your backend server name/ip here.
    35. ProxyPass https://<namespace_route>/oauth/authorize
    36. AuthName "SSO Login"
    37. # For Kerberos
    38. AuthType GSSAPI
    39. Require valid-user
    40. RequestHeader set X-Remote-User %{REMOTE_USER}s
    41. GssapiCredStore keytab:/etc/httpd/protected/auth-proxy.keytab
    42. # Enable the following if you want to allow users to fallback
    43. # to password based authentication when they do not have a client
    44. # configured to perform kerberos authentication.
    45. GssapiBasicAuth On
    46. # For ldap:
    47. # AuthBasicProvider ldap
    48. # AuthLDAPURL "ldap://ldap.example.com:389/ou=People,dc=my-domain,dc=com?uid?sub?(objectClass=*)"
    49. </Location>
    50. <Location /login-proxy/oauth/authorize>
    51. # Insert your backend server name/ip here.
    52. ProxyPass https://<namespace_route>/oauth/authorize
    53. AuthName "SSO Login"
    54. AuthType GSSAPI
    55. Require valid-user
    56. RequestHeader set X-Remote-User %{REMOTE_USER}s env=REMOTE_USER
    57. GssapiCredStore keytab:/etc/httpd/protected/auth-proxy.keytab
    58. # Enable the following if you want to allow users to fallback
    59. # to password based authentication when they do not have a client
    60. # configured to perform kerberos authentication.
    61. GssapiBasicAuth On
    62. ErrorDocument 401 /login.html
    63. </Location>
    64. </VirtualHost>
    65. RequestHeader unset X-Remote-User

    The https://<namespace_route&gt; address is the route to the OAuth server and can be obtained by running oc get route -n openshift-authentication.

  3. Update the identityProviders stanza in the custom resource (CR):

    1. identityProviders:
    2. - name: requestheaderidp
    3. type: RequestHeader
    4. requestHeader:
    5. challengeURL: "https://<namespace_route>/challenging-proxy/oauth/authorize?${query}"
    6. loginURL: "https://<namespace_route>/login-proxy/oauth/authorize?${query}"
    7. ca:
    8. name: ca-config-map
    9. clientCommonNames:
    10. - my-auth-proxy
    11. headers:
    12. - X-Remote-User
  4. Verify the configuration.

    1. Confirm that you can bypass the proxy by requesting a token by supplying the correct client certificate and header:

      1. # curl -L -k -H "X-Remote-User: joe" \
      2. --cert /etc/pki/tls/certs/authproxy.pem \
      3. https://<namespace_route>/oauth/token/request
    2. Confirm that requests that do not supply the client certificate fail by requesting a token without the certificate:

      1. # curl -L -k -H "X-Remote-User: joe" \
      2. https://<namespace_route>/oauth/token/request
    3. Confirm that the challengeURL redirect is active:

      1. # curl -k -v -H 'X-Csrf-Token: 1' \
      2. https://<namespace_route>/oauth/authorize?client_id=openshift-challenging-client&response_type=token

      Copy the challengeURL redirect to use in the next step.

    4. Run this command to show a 401 response with a WWW-Authenticate basic challenge, a negotiate challenge, or both challenges:

      1. # curl -k -v -H 'X-Csrf-Token: 1' \
      2. <challengeURL_redirect + query>
    5. Test logging in to the OpenShift CLI (oc) with and without using a Kerberos ticket:

      1. If you generated a Kerberos ticket by using kinit, destroy it:

        1. # kdestroy -c cache_name (1)
        1Make sure to provide the name of your Kerberos cache.
      2. Log in to the oc tool by using your Kerberos credentials:

        1. # oc login -u <username>

        Enter your Kerberos password at the prompt.

      3. Log out of the oc tool:

        1. # oc logout
      4. Use your Kerberos credentials to get a ticket:

        1. # kinit

        Enter your Kerberos user name and password at the prompt.

      5. Confirm that you can log in to the oc tool:

        1. # oc login

        If your configuration is correct, you are logged in without entering separate credentials.