PingGateway 2024.9

Configuration templates

This page shows template routes for common configurations. Before you start, set up PingGateway as described in Quick install.

Modify the template routes for your deployment. Before you use a route in production, review the points in Security.

Proxy and capture

When you followed the instructions in Quick install, you enabled PingGateway to proxy and capture application requests and server responses.

This template route uses a DispatchHandler to change the scheme to HTTPS on login.

{
  "heap": [
    {
      "name": "ReverseProxyHandler",
      "type": "ReverseProxyHandler",
      "comment": "Testing only: blindly trust the server cert for HTTPS.",
      "config": {
        "tls": {
          "type": "ClientTlsOptions",
          "config": {
            "trustManager": {
              "type": "TrustAllManager"
            },
            "hostnameVerifier": "ALLOW_ALL"
          }
        }
      }
    }
  ],
  "handler": {
    "type": "DispatchHandler",
    "config": {
      "bindings": [
        {
          "condition": "${request.uri.path == '/login'}",
          "handler": "ReverseProxyHandler",
          "baseURI": "https://app.example.com:8444"
        },
        {
          "condition": "${request.uri.scheme == 'http'}",
          "handler": "ReverseProxyHandler",
          "baseURI": "http://app.example.com:8081"
        },
        {
          "handler": "ReverseProxyHandler",
          "baseURI": "https://app.example.com:8444"
        }
      ]
    }
  },
  "condition": "${find(request.uri.query, 'demo=capture')}"
}

Try this example with the sample application:

  1. Add the following route to PingGateway:

    • Linux

    • Windows

    $HOME/.openig/config/routes/20-capture.json
    %appdata%\OpenIG\config\routes\20-capture.json
  2. 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"
    }
  3. Go to http://ig.example.com:8080/login?demo=capture.

    The sample application display the login page.

To use this as a default route with a real application:

  1. Replace the test ReverseProxyHandler with one that is configured to trust the application’s public key server certificate. Otherwise, use a ReverseProxyHandler that references a truststore holding the certificate.

    Configure the ReverseProxyHandler to strictly verifiy hostnames for outgoing SSL connections.

    In production, do not use TrustAllManager for trustManager, or ALLOW_ALL for hostnameVerifier.

  2. Change the baseURI settings to match the target application.

  3. Remove the route-level condition on the handler that specifies a demo query string parameter.

Simple login form

This template route intercepts the login page request, replaces it with a login form, and logs the user into the target application with hard-coded username and password credentials.

{
  "heap": [
    {
      "name": "ReverseProxyHandler",
      "type": "ReverseProxyHandler",
      "comment": "Testing only: blindly trust the server cert for HTTPS.",
      "config": {
        "tls": {
          "type": "ClientTlsOptions",
          "config": {
            "trustManager": {
              "type": "TrustAllManager"
            },
            "hostnameVerifier": "ALLOW_ALL"
          }
        }
      }
    }
  ],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "PasswordReplayFilter",
          "config": {
            "loginPage": "${request.uri.path == '/login'}",
            "request": {
              "method": "POST",
              "uri": "https://app.example.com:8444/login",
              "form": {
                "username": [
                  "MY_USERNAME"
                ],
                "password": [
                  "MY_PASSWORD"
                ]
              }
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  },
  "condition": "${find(request.uri.query, 'demo=simple')}"
}

Try this example with the sample application:

  1. Add the following route to PingGateway:

    • Linux

    • Windows

    $HOME/.openig/config/routes/21-simple.json
    %appdata%\OpenIG\config\routes\21-simple.json
  2. Replace MY_USERNAME with demo, and MY_PASSWORD with Ch4ng31t.

  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. Go to http://ig.example.com:8080/login?demo=simple.

    The sample application profile page for the demo user displays information about the request.

To use this as a default route with a real application:

  1. Replace the test ReverseProxyHandler with one that is configured to trust the application’s public key server certificate. Otherwise, use a ReverseProxyHandler that references a truststore holding the certificate.

    Configure the ReverseProxyHandler to strictly verifiy hostnames for outgoing SSL connections.

    In production, do not use TrustAllManager for trustManager, or ALLOW_ALL for hostnameVerifier.

  2. Change the uri, form, and baseURI to match the target application.

  3. Remove the route-level condition on the handler that specifies a demo query string parameter.

This template route intercepts the login page request, replaces it with the login form, and logs the user into the target application with hard-coded username and password credentials.

The route uses a default CookieFilter to manage cookies. By default, the filter intercepts cookies from the protected application and stores them in the PingGateway session. It does not send the cookies to the browser.

{
  "heap": [
    {
      "name": "ReverseProxyHandler",
      "type": "ReverseProxyHandler",
      "comment": "Testing only: blindly trust the server cert for HTTPS.",
      "config": {
        "tls": {
          "type": "ClientTlsOptions",
          "config": {
            "trustManager": {
              "type": "TrustAllManager"
            },
            "hostnameVerifier": "ALLOW_ALL"
          }
        }
      }
    }
  ],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "PasswordReplayFilter",
          "config": {
            "loginPage": "${request.uri.path == '/login'}",
            "request": {
              "method": "POST",
              "uri": "https://app.example.com:8444/login",
              "form": {
                "username": [
                  "MY_USERNAME"
                ],
                "password": [
                  "MY_PASSWORD"
                ]
              }
            }
          }
        },
        {
          "type": "CookieFilter"
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  },
  "condition": "${find(request.uri.query, 'demo=cookie')}"
}

Try this example with the sample application:

  1. Add the following route to PingGateway:

    • Linux

    • Windows

    $HOME/.openig/config/routes/22-cookie.json
    %appdata%\OpenIG\config\routes\22-cookie.json
  2. Replace MY_USERNAME with kramer, and MY_PASSWORD with N3wman12.

  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. Go to http://ig.example.com:8080/login?demo=cookie.

    The sample application page displays.

  5. Refresh your connection to http://ig.example.com:8080/login?demo=cookie.

    Compared to Login form with cookie from login page, this example displays additional information about the session cookie:

    Cookies  session-cookie=123…​

To use this as a default route with a real application:

  1. Replace the test ReverseProxyHandler with one that is configured to trust the application’s public key server certificate. Otherwise, use a ReverseProxyHandler that references a truststore holding the certificate.

    Configure the ReverseProxyHandler to strictly verifiy hostnames for outgoing SSL connections.

    In production, do not use TrustAllManager for trustManager, or ALLOW_ALL for hostnameVerifier.

  2. Change the uri and form to match the target application.

  3. Remove the route-level condition on the handler that specifies a demo query string parameter.

When a user without a valid session tries to access a protected application, this template route works with an application to return a login page.

The route uses a PasswordReplayFilter to find the login page with a pattern to match a mock AM classic UI page.

The route uses a default CookieFilter to manage cookies. The CookieFilter retains cookies from the browser and doesn’t forward them to the protected application. Similarly, the CookieFilter retains cookies in set-cookie headers from the protected application and doesn’t forward them to the browser.

{
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "PasswordReplayFilter",
          "config": {
            "loginPageContentMarker": "OpenAM\\s\\(Login\\)",
            "request": {
              "comments": [
                "An example based on OpenAM classic UI: ",
                "uri is for the OpenAM login page; ",
                "IDToken1 is the username field; ",
                "IDToken2 is the password field; ",
                "host takes the OpenAM FQDN:port.",
                "The sample app simulates OpenAM."
              ],
              "method": "POST",
              "uri": "http://app.example.com:8081/openam/UI/Login",
              "form": {
                "IDToken0": [
                  ""
                ],
                "IDToken1": [
                  "demo"
                ],
                "IDToken2": [
                  "Ch4ng31t"
                ],
                "IDButton": [
                  "Log+In"
                ],
                "encoded": [
                  "false"
                ]
              },
              "headers": {
                "host": [
                  "app.example.com:8081"
                ]
              }
            }
          }
        },
        {
          "type": "CookieFilter"
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  },
  "condition": "${find(request.uri.query, 'demo=classic')}"
}

Try this example with the sample application:

  1. Save the file as $HOME/.openig/config/routes/23-classic.json.

  2. Use the following curl command to check that it works:

    $ curl -D- http://ig.example.com:8080/login?demo=classic
    
    HTTP/1.1 200 OK
    Set-Cookie: IG_SESSIONID=24446BA29E866F840197C8E0EAD57A89; Path=/; HttpOnly
    ...

To use this as a default route with a real application:

  1. Change the uri and form to match the target application.

  2. Remove the route-level condition on the handler that specifies a demo query string parameter.

Login which requires a hidden value from the login page

This template route extracts a hidden value from the login page and posts a static login form to the target application.

{
  "properties": {
    "appBaseUri":  "https://app.example.com:8444"
  },
  "heap": [
    {
      "name": "ReverseProxyHandler",
      "type": "ReverseProxyHandler",
      "comment": "Testing only: blindly trust the server cert for HTTPS.",
      "config": {
        "tls": {
          "type": "ClientTlsOptions",
          "config": {
            "trustManager": {
              "type": "TrustAllManager"
            },
            "hostnameVerifier": "ALLOW_ALL"
          }
        }
      }
    }
  ],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "PasswordReplayFilter",
          "config": {
            "loginPage": "${request.uri.path == '/login'}",
            "loginPageExtractions": [
              {
                "name": "hidden",
                "pattern": "loginToken\\s+value=\"(.*)\""
              }
            ],
            "request": {
              "method": "POST",
              "uri": "${appBaseUri}/login",
              "form": {
                "username": [
                  "MY_USERNAME"
                ],
                "password": [
                  "MY_PASSWORD"
                ],
                "hiddenValue": [
                  "${attributes.extracted.hidden}"
                ]
              }
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  },
  "condition": "${find(request.uri.query, 'demo=hidden')}",
  "baseURI": "${appBaseUri}"
}

The parameters in the PasswordReplayFilter form, MY_USERNAME and MY_PASSWORD, take string values or expressions.

Try this example with the sample application:

  1. Add the following route to PingGateway:

    • Linux

    • Windows

    $HOME/.openig/config/routes/24-hidden.json
    %appdata%\OpenIG\config\routes\24-hidden.json
  2. Replace MY_USERNAME with scarter, and MY_PASSWORD with S9rain12.

  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. Go to http://ig.example.com:8080/login?demo=hidden.

To use this as a default route with a real application:

  1. Replace the test ReverseProxyHandler with one that is configured to trust the application’s public key server certificate. Otherwise, use a ReverseProxyHandler that references a truststore holding the certificate.

    Configure the ReverseProxyHandler to strictly verifiy hostnames for outgoing SSL connections.

    In production, do not use TrustAllManager for trustManager, or ALLOW_ALL for hostnameVerifier.

  2. Change the loginPage, loginPageExtractions, uri, and form to match the target application.

  3. Remove the route-level condition on the handler that specifies a demo query string parameter.

HTTP and HTTPS application

This template route proxies traffic to an application with both HTTP and HTTPS ports. The application uses HTTPS for authentication and HTTP for the general application features. When all login requests use HTTPS, you must add the login filters and handlers to the chain.

{
  "heap": [
    {
      "name": "ReverseProxyHandler",
      "type": "ReverseProxyHandler",
      "comment": "Testing only: blindly trust the server cert for HTTPS.",
      "config": {
        "tls": {
          "type": "ClientTlsOptions",
          "config": {
            "trustManager": {
              "type": "TrustAllManager"
            },
            "hostnameVerifier": "ALLOW_ALL"
          }
        }
      }
    }
  ],
  "handler": {
    "type": "DispatchHandler",
    "config": {
      "bindings": [
        {
          "condition": "${request.uri.scheme == 'http'}",
          "handler": "ReverseProxyHandler",
          "baseURI": "http://app.example.com:8081"
        },
        {
          "condition": "${request.uri.path == '/login'}",
          "handler": {
            "type": "Chain",
            "config": {
              "comment": "Add one or more filters to handle login.",
              "filters": [],
              "handler": "ReverseProxyHandler"
            }
          },
          "baseURI": "https://app.example.com:8444"
        },
        {
          "handler": "ReverseProxyHandler",
          "baseURI": "https://app.example.com:8444"
        }
      ]
    }
  },
  "condition": "${find(request.uri.query, 'demo=https')}"
}

Try this example with the sample application:

  1. Add the following route to PingGateway:

    • Linux

    • Windows

    $HOME/.openig/config/routes/25-https.json
    %appdata%\OpenIG\config\routes\25-https.json
  2. 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"
    }
  3. Go to http://ig.example.com:8080/login?demo=https.

    The login page of the sample application is displayed.

To use this as a default route with a real application:

  1. Replace the test ReverseProxyHandler with one that is configured to trust the application’s public key server certificate. Otherwise, use a ReverseProxyHandler that references a truststore holding the certificate.

    Configure the ReverseProxyHandler to strictly verifiy hostnames for outgoing SSL connections.

    In production, do not use TrustAllManager for trustManager, or ALLOW_ALL for hostnameVerifier.

  2. Change the loginPage, loginPageExtractions, uri, and form to match the target application.

  3. Remove the route-level condition on the handler that specifies a demo query string parameter.

AM integration with headers

This template route logs the user into the target application using headers like those from AM policy agents. If a header contains only a username or subject to look up in an external data source, you must add an attribute filter to the chain to retrieve the credentials.

{
  "heap": [
    {
      "name": "ReverseProxyHandler",
      "type": "ReverseProxyHandler",
      "comment": "Testing only: blindly trust the server cert for HTTPS.",
      "config": {
        "tls": {
          "type": "ClientTlsOptions",
          "config": {
            "trustManager": {
              "type": "TrustAllManager"
            },
            "hostnameVerifier": "ALLOW_ALL"
          }
        }
      }
    }
  ],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "PasswordReplayFilter",
          "config": {
            "loginPage": "${request.uri.path == '/login'}",
            "request": {
              "method": "POST",
              "uri": "https://app.example.com:8444/login",
              "form": {
                "username": [
                  "${request.headers['username'][0]}"
                ],
                "password": [
                  "${request.headers['password'][0]}"
                ]
              }
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  },
  "condition": "${find(request.uri.query, 'demo=headers')}"
}

Try this example with the sample application:

  1. Add the route to PingGateway:

    • Linux

    • Windows

    $HOME/.openig/config/routes/26-headers.json
    %appdata%\OpenIG\config\routes\26-headers.json
  2. Use the curl command to simulate the headers from a policy agent:

    $ curl \
    --header "username: kvaughan" \
    --header "password: B5ibery12" \
    http://ig.example.com:8080/login?demo=headers
    ...
    <title id="title">Howdy, kvaughan</title>
    ...

To use this as a default route with a real application:

  1. Replace the test ReverseProxyHandler with one that is configured to trust the application’s public key server certificate. Otherwise, use a ReverseProxyHandler that references a truststore holding the certificate.

    Configure the ReverseProxyHandler to strictly verifiy hostnames for outgoing SSL connections.

    In production, do not use TrustAllManager for trustManager, or ALLOW_ALL for hostnameVerifier.

  2. Change the loginPage, uri, and form to match the target application.

  3. Remove the route-level condition on the handler that specifies a demo query string parameter.

Copyright © 2010-2024 ForgeRock, all rights reserved.