PingGateway

Password replay with AM

Password replay brings SSO to legacy web applications without the need to edit, upgrade, or recode them.

Use PingGateway with an appropriate AM authentication tree to capture and replay username password credentials. PingGateway and AM share a secret key to encrypt and decrypt the password and keep it safe.

When running PingOne Advanced Identity Cloud, read Password replay and PingOne Advanced Identity Cloud instead.

Request flow

The following figure illustrates the flow of requests when an unauthenticated user accesses a protected application. After signing on with AM, the user signs on to the application with the username and password from AM.

Password replay sequence diagram
Figure 1. Password replay sequence diagram
  • PingGateway intercepts the browser’s HTTP GET request.

  • PingGateway redirects the user to AM for authentication.

  • AM authenticates the user and stores the encrypted password in a JWT.

  • AM redirects the browser back to the protected application with the JWT.

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

    • The user is authenticated.

    • PingGateway gets the password from the JWT and decrypts it.

    • PingGateway gets the username from AM based on the user _id.

  • PingGateway replaces the request with an HTTP POST to the application, taking the credentials from the context.

  • The sample application validates the credentials from the HTTP POST request.

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

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

Tasks

Before you begin

Before you begin, prepare AM, PingGateway, and the sample application. Learn more in the example installation for this guide.

Task 1: Prepare a shared secret

PingGateway and AM share a secret symmetric key to encrypt and decrypt the password.

The AM authentication tree you will configure includes the JWT Password Replay node to capture the password in an encrypted JWT it sends to PingGateway. The JWT Password Replay node relies on a secret label of the form am.authentication.nodes.jwt.replay.identifier.encryption to get the shared secret key. This example uses pinggateway as the identifier and stores the shared secret in a PEM file whose name is the secret label, am.authentication.nodes.jwt.replay.pinggateway.encryption. When installing AM and PingGateway on the same computer, you can share the PEM file directly.

  1. Create a secrets folder next to the PingGateway instance folder to store the shared secret key:

    $ mkdir secrets
  2. Generate a base64-encoded shared secret using the filename the JWT Password Replay node requires:

    $ echo "-----BEGIN AES SECRET KEY-----" > secrets/am.authentication.nodes.jwt.replay.pinggateway.encryption
    $ head -c32 /dev/urandom | base64 >> secrets/am.authentication.nodes.jwt.replay.pinggateway.encryption
    $ echo "-----END AES SECRET KEY-----" >> secrets/am.authentication.nodes.jwt.replay.pinggateway.encryption

    The file contains the base64-encoded shared secret in PEM format.

You have successfully added a shared secret in the PEM file, ready for AM and PingGateway to use.

Task 2: Configure AM

  1. Select Realms > Top Level Realm > Secret Stores, click + Add Secret Store, and create the new secret store with these settings:

    Secret Store ID

    Files

    Store Type

    File System Secret Volumes

    Directory

    Absolute path to the secrets folder you created

    File format

    PEM encoded certificate, key, or password

    AM can now use the shared secret key stored in the PEM file, secrets/am.authentication.nodes.jwt.replay.pinggateway.encryption.

  2. Select Realms > Top Level Realm > 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/*?*

  3. In the agent profile for PingGateway, add a redirect URI for CDSSO that PingGateway can use in the route for password replay.

    Go to Applications > Agents > Identity Gateway > ig_agent, set Redirect URLs for CDSSO to https://ig.example.com:8443/replay/redirect, and click Save Changes.

  4. Go to Authentication > Trees, click + Create Tree, and create an authentication tree named Password replay configured with the nodes shown in this screenshot:

    Password replay journey

    • The Page node presents a page with input fields to prompt for the username and password.

      • The Username collector node collects and injects the userName into the shared node state.

      • The Password collector node collects and injects the password into the shared node state.

    • The Data Store Decision node uses the username and password to determine whether authentication is successful.

    • The JWT Password Replay node stores the password in a JWT encrypted with the shared secret key.

  5. Make sure the test user can sign on with the tree before continuing.

    To verify the tree works as expected, in your browser’s privacy or incognito mode, go to http://am.example.com:8088/openam/XUI/?service=Password%20replay#login and sing on as test user demo with password Ch4ng31t.

    On success, the browser displays the user’s profile page.

You have successfully configured AM for password replay.

Task 3: Configure PingGateway

The password replay configuration includes the PingGateway password to connect to AM, the shared secret, and the route for password replay.

  1. Set up PingGateway for HTTPS.

  2. Make sure PingGateway connects to the sample application over HTTPS with a route to access static resources.

  3. Set an environment variable locally on the computer running PingGateway to access the base64-encoded agent password:

    $ export AGENT_SECRET_ID='cGFzc3dvcmQ='

    PingGateway retrieves the password with a SystemAndEnvSecretStore, which requires it to be base64-encoded.

    The password must match the agent profile password you set in AM. PingGateway uses the password to connect to AM.

  4. Restart PingGateway to read the secrets from the environment.

  5. Add a route for password replay:

    Linux

    $HOME/.openig/config/routes/04-replay.json

    Windows

    %appdata%\OpenIG\config\routes\04-replay.json

    {
      "name": "04-replay",
      "condition": "${find(request.uri.path, '^/replay')}",
      "properties": {
        "amInstanceUrl": "http://am.example.com:8088/openam/"
      },
      "heap": [
        {
          "name": "SystemAndEnvSecretStore-1",
          "type": "SystemAndEnvSecretStore"
        },
        {
          "name": "AmService-1",
          "type": "AmService",
          "config": {
            "agent": {
              "username": "ig_agent",
              "passwordSecretId": "agent.secret.id"
            },
            "secretsProvider": "SystemAndEnvSecretStore-1",
            "url": "&{amInstanceUrl}"
          }
        },
        {
          "name": "PemPropertyFormat-1",
          "type": "PemPropertyFormat"
        },
        {
          "name": "FileSystemSecretStore-1",
          "type": "FileSystemSecretStore",
          "config": {
            "format": "PLAIN",
            "directory": "&{ig.instance.dir}/../secrets/",
            "mappings": [
              {
                "secretId": "am.authentication.nodes.jwt.replay.pinggateway.encryption",
                "format": "PemPropertyFormat-1"
              }
            ]
          }
        },
        {
          "name": "CapturedUserPasswordFilter-1",
          "type": "CapturedUserPasswordFilter",
          "config": {
            "ssoToken": "${contexts.ssoToken.value}",
            "keySecretId": "am.authentication.nodes.jwt.replay.pinggateway.encryption",
            "secretsProvider": "FileSystemSecretStore-1",
            "amService": "AmService-1"
          }
        },
        {
          "name": "CrossDomainSingleSignOnFilter-1",
          "type": "CrossDomainSingleSignOnFilter",
          "config": {
            "redirectEndpoint": "/replay/redirect",
            "authCookie": {
              "path": "/replay",
              "name": "ig-token-cookie"
            },
            "amService": "AmService-1",
            "authenticationService": "Password replay"
          }
        },
        {
          "name": "UserProfileFilter-1",
          "type": "UserProfileFilter",
          "config": {
            "username": "${contexts.ssoToken.info.uid}",
            "userProfileService": {
              "type": "UserProfileService",
              "config": {
                "amService": "AmService-1",
                "profileAttributes": [
                  "username"
                ]
              }
            }
          }
        },
        {
          "name": "PasswordReplayFilter-1",
          "type": "PasswordReplayFilter",
          "config": {
            "loginPage": "${true}",
            "credentials": "CapturedUserPasswordFilter-1",
            "request": {
              "method": "POST",
              "uri": "https://app.example.com:8444/login",
              "form": {
                "username": [
                  "${contexts.userProfile.username}"
                ],
                "password": [
                  "${contexts.capturedPassword.value}"
                ]
              }
            }
          },
          "capture": [
            "all"
          ]
        }
      ],
      "handler": {
        "type": "Chain",
        "config": {
          "filters": [
            "CrossDomainSingleSignOnFilter-1",
            "UserProfileFilter-1",
            "PasswordReplayFilter-1"
          ],
          "handler": "ReverseProxyHandler"
        }
      }
    }

    Source: 04-replay.json

    The route:

    • Matches requests whose path starts with /replay.

    • Sets an amInstanceUrl property to the URL for AM.

    • Connects to AM as ig_agent with the agent.secret.id password from the local AGENT_SECRET_ID environment variable.

    • Loads the shared secret key from the PEM file.

    • Extracts the captured password from the SSO token context and decrypts it with the shared secret key.

    • Uses a CrossDomainSingleSignOnFilter to redirect to the AM Password replay tree for authentication, getting the authentication information from the ig-token-cookie.

    • Queries AM to retrieve the username for authentication.

      You can retrieve other profile attributes with the UserProfileFilter, such as the email address or first and last names. The sample application expects the username in this example, so the route gets the username.

    • Signs on to the sample application with the username and password.

    • Returns the result to the browser.

    In production, remove "capture": ["all"] from the PasswordReplayFilter to avoid recording credentials in the logs.

Validation

  1. In your browser’s privacy or incognito mode, go to https://ig.example.com:8443/replay/.

    PingGateway redirects to the AM authentication tree.

  2. Sign on as test user demo with password Ch4ng31t.

    PingGateway successfully replays the credentials against the sample application. The sample application displays its user profile page:

    Successful password replay
  3. Review the PingGateway output.

    On success, the output displays the credentials and the profile page:

    ...INFO  o.f.o.d.c.C.c.PasswordReplayFilter-1 @04-replay -
    
    [CONTINUED]--- (filtered-request) exchangeId:<id> - transactionId:<id> --->
    
    [CONTINUED]POST https://app.example.com:8444/login HTTP/1.1
    [CONTINUED]Content-Length: 31
    [CONTINUED]Content-Type: application/x-www-form-urlencoded
    
    [CONTINUED]password=Ch4ng31t&username=demo
    
    ...INFO  o.f.o.d.c.C.c.PasswordReplayFilter-1 @04-replay -
    
    [CONTINUED]<--- (response) exchangeId:<id> - transactionId:<id> ---
    
    [CONTINUED]HTTP/1.1 200 OK
    ...
    
    [CONTINUED]<!DOCTYPE html>
    ...

You have successfully demonstrated password replay with PingGateway and AM.

If password replay fails, consider the outcome of the HTTP POST from PingGateway to the sample application:

HTTP 401 Unauthorized

PingGateway isn’t replaying the credentials.

Review the PingGateway output to determine whether the username or password is missing when PingGateway replays the credentials.

If the password is missing, make sure PingGateway and AM share the same secret key.

HTTP 403 Forbidden

PingGateway isn’t replaying the right credentials.

Make sure you’re using a username-password combination known to the sample application.