Configuring Scriptable Throttling

This section builds on the example in "Configuring Mapped Throttling". It creates a scriptable throttling filter, where the script applies a throttling rate of 6 requests/10 seconds to requests from gold status users. For all other requests, the script returns null, and applies the default rate of 1 request/10 seconds.

Configure Scriptable Throttling
  1. Set up AM as described in "Configure Mapped Throttling".

  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/00-throttle-scriptable.json
      %appdata%\OpenIG\config\routes\00-throttle-scriptable.json
      {
        "name": "00-throttle-scriptable",
        "baseURI": "http://app.example.com:8081",
        "condition": "${matches(request.uri.path, '^/home/throttle-scriptable')}",
        "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://openam.example.com:8088/openam/",
              "version": "7"
            }
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "name": "OAuth2ResourceServerFilter-1",
                "type": "OAuth2ResourceServerFilter",
                "config": {
                  "scopes": [
                    "mail",
                    "employeenumber"
                  ],
                  "requireHttps": false,
                  "realm": "OpenIG",
                  "accessTokenResolver": {
                    "name": "token-resolver-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"
                        }
                      }
                    }
                  }
                }
              },
              {
                "name": "ThrottlingFilter-1",
                "type": "ThrottlingFilter",
                "config": {
                  "requestGroupingPolicy": "${contexts.oauth2.accessToken.info.mail}",
                  "throttlingRatePolicy": {
                    "type": "DefaultRateThrottlingPolicy",
                    "config": {
                      "delegateThrottlingRatePolicy": {
                        "name": "ScriptedPolicy",
                        "type": "ScriptableThrottlingPolicy",
                        "config": {
                          "type": "application/x-groovy",
                          "source": [
                            "if (contexts.oauth2.accessToken.info.status == status) {",
                            "  return new ThrottlingRate(rate, duration)",
                            "} else {",
                            "  return null",
                            "}"
                          ],
                          "args": {
                            "status": "gold",
                            "rate": 6,
                            "duration": "10 seconds"
                          }
                        }
                      },
                      "defaultRate": {
                        "numberOfRequests": 1,
                        "duration": "10 s"
                      }
                    }
                  }
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }

      For information about how to set up the IG route in Studio, see "Scriptable Throttling Filter in Structured Editor".

      Notice the following features of the route, compared to 00-throttle-mapped.json:

      • The route matches requests to /home/throttle-scriptable.

      • The DefaultRateThrottlingPolicy delegates the management of throttling to the ScriptableThrottlingPolicy.

      • The script applies a throttling rate to requests from users with gold status. For all other requests, the script returns null and the default rate is applied.

  3. Test the setup:

    1. Get an access_token for George from AM:

      $ george_token=$(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. Using the access_token for authentication, access the route multiple times. The following example accesses the route 10 times, and writes the output to a file:

      $ curl -v http://openig.example.com:8080/home/throttle-scriptable/\[01-10\] --header "Authorization:Bearer ${george_token}" > /tmp/george.txt 2>&1

    3. Search the output file to see the result:

      $ grep "< HTTP/1.1" /tmp/george.txt | sort | uniq -c
      
      6 < HTTP/1.1 200
      4 < HTTP/1.1 429

      Notice that with a gold status, George can access the route 6 times in 10 seconds.

    4. In AM, change George's email to george@other.com, and then run the last two steps again to see how the access is reduced.

Read a different version of :