PingGateway 2024.9

Password replay from AM

Use PingGateway with AM’s password capture and replay to bring SSO to legacy web applications, without the need to edit, upgrade, or recode. This feature helps you to integrate legacy web applications with other applications using the same user identity.

The following figure illustrates the flow of requests when an unauthenticated user accesses a protected application. After authenticating with AM, the user is logged into the application with the username and password from the AM login session.

Data flow to log in to a protected application
Figure 1. Data flow to log in to a protected application
  • PingGateway intercepts the browser’s HTTP GET request.

  • Because the user is not authenticated, the SingleSignOnFilter redirects the user to AM for authentication.

  • AM authenticates the user, capturing the login credentials, and storing the encrypted password in the user’s AM session.

  • AM redirects the browser back to the protected application.

  • PingGateway intercepts the browser’s HTTP GET request again:

    • The user is now authenticated, so PingGateway’s SingleSignOnFilter passes the request to the CapturedUserPasswordFilter.

    • The CapturedUserPasswordFilter checks that the SessionInfoContext ${contexts.amSession.properties.sunIdentityUserPassword} is available and not null. It then decrypts the password and stores it in the CapturedUserPasswordContext, at ${contexts.capturedPassword}.

  • The PasswordReplayFilter uses the username and decrypted password in the context to replace the request with an HTTP POST of the login form.

  • The sample application validates the credentials.

  • The sample application responds with the user’s profile page.

  • PingGateway then passes the response from the sample application to the browser.

Before you start, prepare AM, PingGateway, and the sample application as described in Example installation for this guide.

In PingOne Advanced Identity Cloud and from AM 7.5, the password capture and replay feature can optionally manage the replay password through AM’s secret service. The secret label for the replay password must be am.authentication.replaypassword.key.

For backward compatibility, if a secret isn’t defined, is empty, or can’t be resolved, AM manages the replay password through the AM system property am.authentication.replaypassword.key.

The following steps use the AM default aestest 256-bit AES test key as the shared secret. AM uses the key to encrypt the password and PingGateway uses it to decrypt the password. Do not use the test key in production:

  1. Set up AM:

    1. Select Services > Add a Service and add a Validation Service with the following Valid goto URL Resources:

      • https://ig.example.com:8443/*

      • https://ig.example.com:8443/*?*

    2. Register a PingGateway agent with the following values, as described in Register a PingGateway agent in AM:

      • Agent ID: ig_agent

      • Password: password

        Use secure passwords in a production environment. Consider using a password manager to generate secure passwords.
    3. (Optional) Authenticate the agent to AM as described in Authenticate a PingGateway agent to AM.

      PingGateway agents are automatically authenticated to AM by a deprecated authentication module in AM. This step is currently optional, but will be required when authentication chains and modules are removed in a future release of AM.
    4. Update the Authentication Post Processing Classes for password replay:

      1. Select Authentication > Settings > Post Authentication Processing.

      2. In Authentication Post Processing Classes, add com.sun.identity.authentication.spi.JwtReplayPassword.

    5. Select Configure > Secret Stores > default-keystore in the global secret stores list.

      1. Switch to the Mappings tab and click + Add Mapping

        Secret Label

        am.authentication.replaypassword.key

        Aliases

        Add aestest (not for use in production)

        Use an appropriate global secret store and 256-bit AES key in production, not the test key. AM 7.5 requires adding the am.authentication.replaypassword.key mapping to a global secret store, not a realm-based secret store.

        How you generate the key depends on the secret store. For example, the openssl rand -base64 32 command generates a base64-encoded 256-bit string. The keytool -genseckey -alias my-aes-key -keyalg AES -keysize 256 command generates a 256-bit symmetric key in a Java keystore.

      2. Click Create to complete the mapping.

    6. Select Configure > Global Services > Platform, and add example.com as an AM cookie domain.

      By default, AM sets host-based cookies. After authentication with AM, requests can be redirected to AM instead of to the resource.

  2. Set up PingGateway:

    1. Set up PingGateway for HTTPS, as described in Configure PingGateway for TLS (server-side).

    2. Set environment variables for the value of the AES 256-bit key, and the PingGateway agent password, and then restart PingGateway:

      # The base64-encoded "aestest" key:
      $ export AES_KEY='YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd5eHowMTIzNDU='
      # The base64-encoded PingGateway agent "password":
      $ export AGENT_SECRET_ID='cGFzc3dvcmQ='
    3. Add the following route to PingGateway to serve the sample application .css and other static resources:

      • Linux

      • Windows

      $HOME/.openig/config/routes/00-static-resources.json
      %appdata%\OpenIG\config\routes\00-static-resources.json
      {
        "name" : "00-static-resources",
        "baseURI" : "http://app.example.com:8081",
        "condition": "${find(request.uri.path,'^/css') or matchesWithRegex(request.uri.path, '^/.*\\\\.ico$') or matchesWithRegex(request.uri.path, '^/.*\\\\.gif$')}",
        "handler": "ReverseProxyHandler"
      }
    4. Add the following route to PingGateway:

      • Linux

      • Windows

      $HOME/.openig/config/routes/04-replay.json
      %appdata%\OpenIG\config\routes\04-replay.json
      {
        "name": "04-replay",
        "condition": "${find(request.uri.path, '^/replay')}",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore",
            "config": {
              "mappings": [
                {
                  "secretId": "aes.key",
                  "format": {
                    "type": "SecretKeyPropertyFormat",
                    "config": {
                      "format": "BASE64",
                      "algorithm": "AES"
                    }
                  }
                }
              ]
            }
          },
          {
            "name": "AmService-1",
            "type": "AmService",
            "config": {
              "agent": {
                "username": "ig_agent",
                "passwordSecretId": "agent.secret.id"
              },
              "secretsProvider": "SystemAndEnvSecretStore-1",
              "url": "http://am.example.com:8088/openam/"
            }
          },
          {
            "name": "CapturedUserPasswordFilter",
            "type": "CapturedUserPasswordFilter",
            "config": {
              "ssoToken": "${contexts.ssoToken.value}",
              "keySecretId": "aes.key",
              "keyType": "AES",
              "secretsProvider": "SystemAndEnvSecretStore-1",
              "amService": "AmService-1"
            }
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "type": "SingleSignOnFilter",
                "config": {
                  "amService": "AmService-1"
                }
              },
              {
                "type": "PasswordReplayFilter",
                "config": {
                  "loginPage": "${true}",
                  "credentials": "CapturedUserPasswordFilter",
                  "request": {
                    "method": "POST",
                    "uri": "http://app.example.com:8081/login",
                    "form": {
                      "username": [
                        "${contexts.ssoToken.info.uid}"
                      ],
                      "password": [
                        "${contexts.capturedPassword.value}"
                      ]
                    }
                  }
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }

      Notice the following features of the route:

      • The route matches requests to /replay.

      • The agent password for AmService is provided by a SystemAndEnvSecretStore in the heap.

      • If the request does not have a valid AM session cookie, the SingleSignOnFilter redirects the request to AM for authentication.

        After authentication, the SingleSignOnFilter passes the request to the next filter, storing the cookie value in an SsoTokenContext.

      • The PasswordReplayFilter uses the CapturedUserPasswordFilter declared in the heap to retrieve the AM password from AM session properties. The CapturedUserPasswordFilter uses the AES 256-bit key to decrypt the password, and then makes it available in a CapturedUserPasswordContext.

        The value of the AES 256-bit key is provided by the SystemAndEnvSecretStore.

        The PasswordReplayFilter retrieves the username and password from the context. It replaces the browser’s original HTTP GET request with an HTTP POST login request containing the credentials to authenticate to the sample application.

  3. Test the setup:

    1. In your browser’s privacy or incognito mode, go to https://ig.example.com:8443/replay. The SingleSignOnFilter redirects the request to AM for authentication.

    2. If you see warnings that the site isn’t secure, respond to the warnings to access the site.

    3. Log in to AM as user demo, password Ch4ng31t. The request is redirected to the sample application.

Copyright © 2010-2024 ForgeRock, all rights reserved.