Protecting an API With Freeform Designer

This section describes how to use freeform designer to protect APIs, using AM as an OAuth 2.0 authorization server.

The generated route contains a chain of objects to authenticate the user, throttle the rate of requests to the API, and, finally, forward the request to the sample app.

Protect an API With Freeform Designer

Before you start, set up AM as described in "Validating Access_Tokens Through the Introspection Endpoint". In addition, create an OAuth 2.0 Client authorized to introspect tokens, with the following values:

  • Client ID: resource-server

  • Client secret: password

  • Scope(s): am-introspect-all-tokens

  1. In IG Studio, create a route:

    1. Go to http://openig.example.com:8080/openig/studio, and select Create a route.

    2. Select Freeform to use the freeform designer.

  2. Select API Security to use the template for protecting APIs.

  3. Select Advanced options on the right, and create a route with the following options:

    • Base URI: http://app.example.com:8081

    • Condition: Path: /home/rs-introspect-ff

    • Name: rs-introspect-ff

    • AM Configuration:

      • URI: http://openam.example.com:8088/openam

      • Username: ig_agent

      • Password: password

      • Scopes: mail, employeenumber

    The route is displayed on the Flow tab of the canvas.

    Notice that the Start, Chain, and ReverseProxyHandler objects are connected by solid lines, but other objects, such as Authenticate to Am Chain, are connected by a fading line. Objects connected by a fading line are used by other objects in the route.

    Select the All Objects tab to view a list of objects in the route. Double-click on any object to review or edit it. After double-clicking on an object, select the Decorations tab to decorate it.

  4. On the Flow tab, double-click the OAuth2RS object, and edit it as follows:

    • Require HTTPS: Deselect this option

    • Realm: OpenIG

    Leave the other values as they are.

  5. On the top-right of the screen, select and Display to review the route.

    {
      "name": "rs-introspect-ff",
      "baseURI": "http://app.example.com:8081",
      "condition": "${matches(request.uri.path, '^/home/rs-introspect-ff')}",
      "handler": "Chain",
      "properties": {
        "amUsername": "ig_agent",
        "amPassword": "password"
      },
      "heap": [
        {
          "name": "ClientHandler",
          "type": "ClientHandler"
        },
        {
          "name": "Chain",
          "type": "Chain",
          "config": {
            "handler": "ReverseProxyHandler",
            "filters": [
              "OAuth2RS",
              "Throttling"
            ]
          }
        },
        {
          "type": "OAuth2ResourceServerFilter",
          "name": "OAuth2RS",
          "config": {
            "requireHttps": false,
            "realm": "OpenIG",
            "scopes": [
              "mail",
              "employeenumber"
            ],
            "accessTokenResolver": "TokenIntrospectionAccessTokenResolver"
          }
        },
        {
          "type": "TokenIntrospectionAccessTokenResolver",
          "name": "TokenIntrospectionAccessTokenResolver",
          "config": {
            "amService": "AmService",
            "providerHandler": "Authenticate to AM Chain"
          }
        },
        {
          "name": "ReverseProxyHandler",
          "type": "ReverseProxyHandler"
        },
        {
          "name": "AmService",
          "type": "AmService",
          "config": {
            "url": "http://openam.example.com:8088/openam",
            "realm": "/",
            "agent": {
              "username": "${amUsername}",
              "password": "${amPassword}"
            },
            "sessionCache": {
              "enabled": false
            }
          }
        },
        {
          "name": "Authenticate to AM Chain",
          "type": "Chain",
          "config": {
            "handler": "ClientHandler",
            "filters": [
              "Authenticate to AM Filter"
            ]
          }
        },
        {
          "name": "Authenticate to AM Filter",
          "type": "HeaderFilter",
          "config": {
            "messageType": "REQUEST",
            "add": {
              "Authorization": [
                "Basic ${encodeBase64(join(array(amUsername, amPassword), ':'))}"
              ]
            }
          }
        },
        {
          "name": "Throttling",
          "type": "ThrottlingFilter",
          "config": {
            "requestGroupPolicy": "${contexts.oauth2.info.sub}",
            "rate": {
              "numberOfRequests": 60,
              "duration": "60 s"
            }
          }
        },
        {
          "type": "BaseUriDecorator",
          "name": "baseUri"
        },
        {
          "type": "TimerDecorator",
          "name": "timer",
          "config": {
            "timeUnit": "ms"
          }
        },
        {
          "type": "CaptureDecorator",
          "name": "capture",
          "config": {
            "captureEntity": false,
            "captureContext": false,
            "maxEntityLength": 524288
          }
        }
      ]
    }
  6. Select Deploy to push the route to the IG configuration.

    You can check the $HOME/.openig/config/routes folder to see that the route is there.

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. Validate the access_token returned in the previous step:

    $ curl -v http://openig.example.com:8080/home/rs-introspect-ff --header "Authorization: Bearer ${mytoken}"

    The HTML of the sample application is returned.

Read a different version of :