Configuring single sign-on (SSO) for WebSphere Liberty operators

An administrator can configure single sign-on (SSO) for WebSphere® Liberty operators to authenticate and manage users. Authentication can be delegated to external providers, such as Google, Facebook, LinkedIn, Twitter, GitHub, or any OpenID Connect (OIDC) or OAuth 2.0 clients.

Procedure

  1. Configure and build the application image with single sign-on. Follow the instructions in Moving applications to containers and Configuring single sign-on (SSO) for applications in containers.
  2. Complete one of these choices to configure SSO in your operator.

Configuring SSO with specified client IDs and secrets

The operator can specify a client ID and secret in advance. A disadvantage to this configuration is that the client ID and secret must be supplied for registration repetitively, rather than automatically with the provider administrator supplying the information needed for registration one time.

  1. Create a secret that specifies sensitive information such as client IDs, client secrets, and tokens for the login providers you selected in application image.

    Create the Secret named WebSphereLibertyApplication_name-wlapp-sso in the same namespace as the WebSphereLibertyApplication instance. In the following sample snippets, WebSphereLibertyApplication is named my-app, so the secret must be named my-app-wlapp-sso. Both are in the same namespace called demo.

    The keys within the Secret must follow the provider_name-sensitive_field_name naming pattern. For example, google-clientSecret. Instead of a - character in between, you can also use . or _. For example, oauth2_userApiToken.

    apiVersion: v1
    kind: Secret
    metadata:
      # Name of the secret should be in this format: <WebSphereLibertyApplication_name>-wlapp-sso
      name: my-app-wlapp-sso
      # Secret must be created in the same namespace as the WebSphereLibertyApplication instance
      namespace: demo
    type: Opaque
    data:
      # The keys must be in this format: <provider_name>-<sensitive_field_name>
      github-clientId: bW9vb29vb28=
      github-clientSecret: dGhlbGF1Z2hpbmdjb3c=
      twitter-consumerKey: bW9vb29vb28=
      twitter-consumerSecret: dGhlbGF1Z2hpbmdjb3c=
      oidc-clientId: bW9vb29vb28=
      oidc-clientSecret: dGhlbGF1Z2hpbmdjb3c=
      oauth2-clientId: bW9vb29vb28=
      oauth2-clientSecret: dGhlbGF1Z2hpbmdjb3c=
      oauth2-userApiToken: dGhlbGF1Z2hpbmdjb3c=

    The operator watches for the creation and deletion of the SSO secret and any updates to it. Adding, updating, or removing keys from the secret are passed down to the application automatically.

  2. Configure single sign-on in the WebSphereLibertyApplication custom resource (CR). At minimum, set the .spec.sso: {} field so that the operator can pass the values from the secret to your application. Refer to the WebSphereLibertyApplication CR for more SSO configurations.
  3. Configure secured Service and secured Route with necessary certificates. Refer to Certificates for more information.
  4. To automatically trust certificates from popular identity providers, including social login providers such as Google and Facebook, set the SEC_TLS_TRUSTDEFAULTCERTS environment variable to true. To automatically trust certificates issued by the Kubernetes cluster, set environment variable SEC_IMPORT_K8S_CERTS to true. Alternatively, you can include the necessary certificates manually when building application image or mounting them using a volume when you deploy your application.
    apiVersion: liberty.websphere.ibm.com/v1
    kind: WebSphereLibertyApplication
    metadata:
      name: my-app
      namespace: demo
    spec:
      applicationImage: quay.io/my-repo/my-app:1.0
      env:
        - name: SEC_TLS_TRUSTDEFAULTCERTS
          value: "true"
        - name: SEC_IMPORT_K8S_CERTS
          value: "true"
      sso:
        redirectToRPHostAndPort: https://redirect-url.mycompany.com
        github:
          hostname: github.mycompany.com
        oauth2:
          - authorizationEndpoint: specify-required-value
            tokenEndpoint: specify-required-value
        oidc:
          - discoveryEndpoint: specify-required-value
      service:
        certificateSecretRef: mycompany-service-cert
        port: 9443
        type: ClusterIP
      expose: true
      route:
        certificateSecretRef: mycompany-route-cert
        termination: reencrypt

Configuring SSO automatic registration with OIDC providers

The operator can request a client ID and client secret from providers, rather than requiring them in advance. This ability can simplify deployment, as the provider administrator can supply the information that is needed for registration one time, instead of supplying client IDs and secrets repetitively. The callback URL from the provider to the client is supplied by the operator, so doesn't need to be known in advance.

  1. Add attributes that are named provider_name-autoreg-field_name to the Kubernetes secret.

    First, the operator makes an https request to the .spec.sso.oidc[].discoveryEndpoint field to obtain URLs for subsequent REST calls. Next, it makes other REST calls to the provider and obtains a client ID and client secret. The Kubernetes secret is updated with the obtained values.

  2. For Red Hat® Single Sign-on (RH-SSO), you can set the .spec.sso.oidc[].userNameAttribute field to preferred_username to obtain the user ID that was used to log in. For IBM Security Verify, set the field to given_name.

    The following example secret is tested on Red Hat OpenShift® with RH-SSO and IBM® Security Verify.

    apiVersion: v1
    kind: Secret
    metadata:
      # Name of the secret should be in this format: <WebSphereLibertyApplication_name>-wlapp-sso
      name: my-app-wlapp-sso
      # Secret must be created in the same namespace as the WebSphereLibertyApplication instance
      namespace: demo
    type: Opaque
    data:
      # base64 encode the data before entering it here.
      #
      # Leave the clientId and secret out, registration will obtain them and update their values.
      # oidc-clientId
      # oidc-clientSecret
      #
      # Reserved: <provider>-autoreg-RegisteredClientId and RegisteredClientSecret
      # are used by the operator to store a copy of the clientId and clientSecret values.
      #
      # Automatic registration attributes have -autoreg- after the provider name.
      #
      # Red Hat Single Sign On requires an initial access token for registration.
      oidc-autoreg-initialAccessToken: xxxxxyyyyy
      #
      # IBM Security Verify requires a special clientId and clientSecret for registration.
      # oidc-autoreg-initialClientId: bW9vb29vb28=
      # oidc-autoreg-initialClientSecret: dGhlbGF1Z2hpbmdjb3c=
      #
      # Optional: Grant types are the types of OAuth flows the resulting clients will allow
      # Default is authorization_code,refresh_token. Specify a comma separated list.
      # oidc-autoreg-grantTypes: base64 data goes here
      #
      # Optional: Scopes limit the types of information about the user that the provider will return.
      # Default is openid,profile. Specify a comma-separated list.
      # oidc-autoreg-scopes: base64 data goes here
      #
      # Optional: To skip TLS certificate checking with the provider during registration, specify insecureTLS as true. 
      # Default is false.
      # oidc-autoreg-insecureTLS: dHJ1ZQ==

Configuring multiple OIDC and OAuth 2.0 providers

You can authenticate with multiple OIDC and OAuth 2.0 providers.

  1. Configure and build application image with multiple OIDC or OAuth 2.0 providers.

    For example, set the provider name in your Dockerfile. The provider name must be unique and must contain only alphanumeric characters.

    ARG SEC_SSO_PROVIDERS="google oidc:provider1,provider2 oauth2:provider3,provider4"
  2. Use the provider name in an SSO Secret to specify its client ID and secret.

    For example, the following Secret sets provider1-clientSecret: dGhlbGF1Z2hpbmdjb3c= for a client ID and secret.

    apiVersion: v1
    kind: Secret
    metadata:
      # Name of the secret should be in this format: <WebSphereLibertyApplication_name>-wlapp-sso
      name: my-app-wlapp-sso
      # Secret must be created in the same namespace as the WebSphereLibertyApplication instance
      namespace: demo
    type: Opaque
    data:
      # The keys must be in this format: <provider_name>-<sensitive_field_name>
      google-clientId: xxxxxxxxxxxxx
      google-clientSecret: yyyyyyyyyyyyyy
      provider1-clientId: bW9vb29vb28=
      provider1-clientSecret: dGhlbGF1Z2hpbmdjb3c=
      provider2-autoreg-initialClientId: bW9vb29vb28=
      provider2-autoreg-initialClientSecret: dGhlbGF1Z2hpbmdjb3c=
      provider3-clientId: bW9vb29vb28=
      provider3-clientSecret: dGhlbGF1Z2hpbmdjb3c=
      provider4-clientId: bW9vb29vb28=
      provider4-clientSecret: dGhlbGF1Z2hpbmdjb3c=
  3. Configure a field for each corresponding provider in the WebSphereLibertyApplication CR. Use one or both of the .spec.sso.oidc[].id and .spec.sso.oauth2[].id fields.
    sso:
      oidc:
        - id: provider1
          discoveryEndpoint: specify-required-value
        - id: provider2
          discoveryEndpoint: specify-required-value
      oauth2:
        - id: provider3
          authorizationEndpoint: specify-required-value
          tokenEndpoint: specify-required-value
        - id: provider4
          authorizationEndpoint: specify-required-value
          tokenEndpoint: specify-required-value