---
title: OAuth 2.0 context for authentication with PingAM
description: This section contains an example route that retrieves scopes from a token introspection, assigns them as the PingGateway session username and password, and uses them to log the user directly in to the sample application.
component: pinggateway
version: 2025.9
page_id: pinggateway:gateway-guide:oauth2-rs-pwreplay
canonical_url: https://docs.pingidentity.com/pinggateway/2026/gateway-guide/oauth2-rs-pwreplay.html
llms_txt: https://docs.pingidentity.com/pinggateway/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
superseded_by: https://docs.pingidentity.com/pinggateway/2026/gateway-guide/oauth2-rs-pwreplay.html
---

# OAuth 2.0 context for authentication with PingAM

This section contains an example route that retrieves scopes from a token introspection, assigns them as the PingGateway session username and password, and uses them to log the user directly in to the sample application.

For information about the context, refer to [OAuth2Context](../reference/OAuth2Context.html).

Before you start, set up and test the example in [Validating PingAM access tokens with introspection](oauth2-rs-introspect.html).

1. Set up AM:

   1. Select [icon: address-card, set=fa]Identities, and change the email address of the demo user to `demo`.

   2. Select [icon: code, set=fa]Scripts > OAuth2 Access Token Modification Script, and replace the default script as follows:

      ```groovy
      import org.forgerock.http.protocol.Request
      import org.forgerock.http.protocol.Response
      import com.iplanet.sso.SSOException
      import groovy.json.JsonSlurper

      def attributes = identity.getAttributes(["mail"].toSet())
      accessToken.setField("mail", attributes["mail"][0])
      accessToken.setField("password", "Ch4ng31t")
      ```

      The AM script adds user profile information to the access token, and adds a `password` field with the value `Ch4ng31t`.

      |   |                                                                                                                                                   |
      | - | ------------------------------------------------------------------------------------------------------------------------------------------------- |
      |   | Don't use this example in production. If the token is stateless and unencrypted, the password value is easily accessible when you have the token. |

2. Set up PingGateway:

   1. Add the following route to PingGateway:

      * Linux

        `$HOME/.openig/config/routes/rs-pwreplay.json`

      * Windows

        `%appdata%\OpenIG\config\routes\rs-pwreplay.json`

      ```json
      {
        "name" : "rs-pwreplay",
        "baseURI" : "http://app.example.com:8081",
        "condition" : "${find(request.uri.path, '^/rs-pwreplay')}",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore"
          },
          {
            "name": "AmService-1",
            "type": "AmService",
            "config": {
              "agent": {
                "username": "ig_agent",
                "passwordSecretId": "agent.secret.id"
              },
              "secretsProvider": "SystemAndEnvSecretStore-1",
              "url": "http://am.example.com:8088/openam/"
            }
          }
        ],
        "handler" : {
          "type" : "Chain",
          "config" : {
            "filters" : [
              {
                "name" : "OAuth2ResourceServerFilter-1",
                "type" : "OAuth2ResourceServerFilter",
                "config" : {
                  "scopes" : [ "mail", "employeenumber" ],
                  "requireHttps" : false,
                  "accessTokenResolver": {
                    "name": "TokenIntrospectionAccessTokenResolver-1",
                    "type": "TokenIntrospectionAccessTokenResolver",
                    "config": {
                      "amService": "AmService-1",
                      "providerHandler": {
                        "type": "Chain",
                        "config": {
                          "filters": [
                            {
                              "type": "HttpBasicAuthenticationClientFilter",
                              "config": {
                                "username": "ig_agent",
                                "passwordSecretId": "agent.secret.id",
                                "secretsProvider": "SystemAndEnvSecretStore-1"
                              }
                            }
                          ],
                          "handler": "ForgeRockClientHandler"
                        }
                      }
                    }
                  }
                }
              },
              {
                "type": "AssignmentFilter",
                "config": {
                  "onRequest": [{
                    "target": "${session.username}",
                    "value": "${contexts.oauth2.accessToken.info.mail}"
                  },
                    {
                      "target": "${session.password}",
                      "value": "${contexts.oauth2.accessToken.info.password}"
                    }
                  ]
                }
              },
              {
                "type": "StaticRequestFilter",
                "config": {
                  "method": "POST",
                  "uri": "http://app.example.com:8081/login",
                  "form": {
                    "username": [
                      "${session.username}"
                    ],
                    "password": [
                      "${session.password}"
                    ]
                  }
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }
      ```

      Source: [rs-pwreplay.json](../_attachments/config/routes/rs-pwreplay.json)

      Notice the following features of the route compared to `rs-introspect.json`:

      * The route matches requests to `/rs-pwreplay`.

      * The AssignmentFilter accesses the context, and injects the username and password into the SessionContext, `${Session}`.

      * The StaticRequestFilter retrieves the username and password from `session`, and replaces the original HTTP GET request with an HTTP POST login request that contains the credentials to authenticate.

3. Test the setup:

   1. In a terminal window, use a `curl` command similar to the following to retrieve an access token:

      ```console
      $ mytoken=$(curl -s \
      --user "client-application:password" \
      --data "grant_type=password&username=demo&password=Ch4ng31t&scope=mail%20employeenumber" \
      http://am.example.com:8088/openam/oauth2/access_token | jq -r ".access_token")
      ```

   2. Validate the access token returned in the previous step:

      ```console
      $ curl -v \
      --cacert /path/to/secrets/ig.example.com-certificate.pem \
      --header "Authorization: Bearer ${mytoken}" \
      https://ig.example.com:8443/rs-pwreplay
      ```

      HTML for the sample application is displayed.
