Caching Access_Tokens

This section builds on the example in "Validating Access_Tokens Through the Introspection Endpoint" to cache access_tokens.

When the access_token is not cached, IG calls AM to validate the access_token. After the access_token is cached, IG doesn't validate the access_token with AM.

(From AM 6.5.3.) When an access_token is revoked on AM, the CacheAccessTokenResolver can delete the token from the cache when both of the following conditions are true:

  • The notification property of AmService is enabled.

  • The delegate AccessTokenResolver provides the token metadata required to update the cache.

When a refresh_token is revoked on AM, all associated access_tokens are automatically and immediately revoked.

Cache Access_Tokens
  1. Set up AM as described in "Validating Access_Tokens Through the Introspection Endpoint".

  2. Set up IG:

    1. Set an environment variable for the IG agent password, and then restart IG:

      $ export AGENT_SECRET_ID='cGFzc3dvcmQ='

      The password is retrieved by a SystemAndEnvSecretStore, and must be base64-encoded.

    2. Add the following route to IG:

      $HOME/.openig/config/routes/rs-introspect-cache.json
      %appdata%\OpenIG\config\routes\rs-introspect-cache.json
      {
        "name": "rs-introspect-cache",
        "baseURI": "http://app.example.com:8081",
        "condition": "${matches(request.uri.path, '^/rs-introspect-cache$')}",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore"
          },
          {
            "name": "AmService-1",
            "type": "AmService",
            "config": {
              "url": "http://openam.example.com:8088/openam",
              "realm": "/",
              "version": "7",
              "agent" : {
                "username" : "ig_agent",
                "passwordSecretId" : "agent.secret.id"
              },
              "secretsProvider": "SystemAndEnvSecretStore-1"
            }
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "name": "OAuth2ResourceServerFilter-1",
                "type": "OAuth2ResourceServerFilter",
                "config": {
                  "scopes": [
                    "mail",
                    "employeenumber"
                  ],
                  "requireHttps": false,
                  "realm": "OpenIG",
                  "accessTokenResolver": {
                    "name": "CacheAccessTokenResolver-1",
                    "type": "CacheAccessTokenResolver",
                    "config": {
                      "enabled": true,
                      "defaultTimeout ": "1 hour",
                      "maximumTimeToCache": "1 day",
                      "delegate": {
                        "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": {
                                "type": "Delegate",
                                "capture": "all",
                                "config": {
                                  "delegate": "ForgeRockClientHandler"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            ],
            "handler": {
              "type": "StaticResponseHandler",
              "config": {
                "status": 200,
                "headers": {
                  "Content-Type": [ "text/html" ]
                },
                "entity": "<html><body><h2>Decoded access_token: ${contexts.oauth2.accessToken.info}</h2></body></html>"
              }
            }
          }
        }
      }
      

      Notice the following features of the route compared to rs-introspect.json, in "Validating Access_Tokens Through the Introspection Endpoint":

      • The OAuth2ResourceServerFilter uses a CacheAccessTokenResolver to cache the access_token, and then delegate token resolution to the TokenIntrospectionAccessTokenResolver.

      • The TokenIntrospectionAccessTokenResolver uses a ForgeRockClientHandler and a capture decorator to capture IG's interactions with AM.

  3. Test the setup:

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

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

    2. Access the route, using the access_token returned in the previous step:

      $ curl http://openig.example.com:8080/rs-introspect-cache --header "Authorization: Bearer ${mytoken}"
      
      {
       active = true,
       scope = employeenumber mail,
       client_id = client - application,
       user_id = george,
       token_type = Bearer,
       exp = 158...907,
       sub = george,
       iss = http://openam.example.com:8088/openam/oauth2, ...
       ...
      }
    3. In the route log, note that IG calls AM to introspect the access_token:

      POST http://openam.example.com:8088/openam/oauth2/realms/root/introspect HTTP/1.1

    4. Access the route again, and in the route log note that this time IG doesn't call AM, because the token is cached.

      Disable the cache and repeat the previous steps to cause IG to call AM to validate the access_token for each request.

Read a different version of :