Using AM As a Single OpenID Connect Provider

This section gives an example of how to set up AM as an OpenID Connect identity provider, and IG as a relying party for browser requests to the home page of the sample application.

The following sequence diagram shows the flow of information for a request to access the home page of the sample application, using AM as a single, preregistered OpenID Connect identity provider, and IG as a relying party:


Use AM As a Single OpenID Connect Provider

Before you start, prepare AM, IG, and the sample application as described in "Example Installation for This Guide".

  1. Set Up AM as an OpenID Connect provider:

    1. Select Identities, and add a user with the following values:

      • ID/username: george

      • First name: george

      • Last name: costanza

      • Password: C0stanza

      • Email Address: george@example.com

      • Employee number: 123

    2. (For AM 6.5.3 and later versions) Select  Services > Add a Service, and add a Validation Service with the following Valid goto URL Resources:

      • http://openig.example.com:8080/*

      • http://openig.example.com:8080/*?*

    3. Create an OAuth 2.0 Authorization Server:

      1. Select  Services > Add a Service > OAuth2 Provider.

      2. Add a service with the default values.

    4. Create an OAuth 2.0 Client to request OAuth 2.0 access_tokens:

      1. Select Applications > OAuth 2.0 > Clients.

      2. Add a client with the following values:

        • Client ID: oidc_client

        • Client secret: password

        • Redirection URIs: http://openig.example.com:8080/home/id_token/callback

        • Scope(s): openid, profile, and email

    5. (From AM 6.5) On the Advanced tab, select the following values:

      • Grant Types: Authorization Code and Resource Owner Password Credentials

    6. On the Signing and Encryption tab, change ID Token Signing Algorithm to HS256, HS384, or HS512. The algorithm must be HMAC.

    7. Log out of AM.

  2. Set up IG:

    1. Set an environment variable for oidc_client, and then restart IG:

      $ export OIDC_SECRET_ID='cGFzc3dvcmQ='
    2. Add the following route to IG, to serve .css and other static resources for the sample application:

      $HOME/.openig/config/routes/static-resources.json
      %appdata%\OpenIG\config\routes\static-resources.json
      {
        "name" : "sampleapp_resources",
        "baseURI" : "http://app.example.com:8081",
        "condition": "${matches(request.uri.path,'^/css')}",
        "handler": "ReverseProxyHandler"
      }
    3. Add the following route to IG:

      $HOME/.openig/config/routes/07-openid.json
      %appdata%\OpenIG\config\routes\07-openid.json
      {
        "name": "07-openid",
        "baseURI": "http://app.example.com:8081",
        "condition": "${matches(request.uri.path, '^/home/id_token')}",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore"
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "name": "OAuth2ClientFilter-1",
                "type": "OAuth2ClientFilter",
                "config": {
                  "clientEndpoint": "/home/id_token",
                  "failureHandler": {
                    "type": "StaticResponseHandler",
                    "config": {
                      "status": 500,
                      "headers": {
                        "Content-Type": [
                          "text/plain"
                        ]
                      },
                      "entity": "Error in OAuth 2.0 setup."
                    }
                  },
                  "registrations": [
                    {
                      "name": "oidc-user-info-client",
                      "type": "ClientRegistration",
                      "config": {
                        "clientId": "oidc_client",
                        "clientSecretId": "oidc.secret.id",
                        "issuer": {
                          "name": "Issuer",
                          "type": "Issuer",
                          "config": {
                            "wellKnownEndpoint": "http://openam.example.com:8088/openam/oauth2/.well-known/openid-configuration"
                          }
                        },
                        "scopes": [
                          "openid",
                          "profile",
                          "email"
                        ],
                        "secretsProvider": "SystemAndEnvSecretStore-1",
                        "tokenEndpointAuthMethod": "client_secret_basic"
                      }
                    }
                  ],
                  "requireHttps": false,
                  "cacheExpiration": "disabled"
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }

      For information about how to set up the IG route in Studio, see "OpenID Connect Relying Party in Structured Editor".

      Notice the following features about the route:

      • The route matches requests to /home/id_token.

      • The OAuth2ClientFilter enables IG to act as a relying party. It uses a single client registration that is defined inline and refers to the AM server configured in "Using AM As a Single OpenID Connect Provider".

      • The filter has a base client endpoint of /home/id_token, which creates the following service URIs:

        • Requests to /home/id_token/login start the delegated authorization process.

        • Requests to /home/id_token/callback are expected as redirects from the OAuth 2.0 Authorization Server (OpenID Connect provider). This is why the redirect URI in the client profile in AM is set to http://openig.example.com:8080/home/id_token/callback.

        • Requests to /home/id_token/logout remove the authorization state for the end user, and redirect to the specified URL if a goto parameter is provided.

        These endpoints are implicitly reserved. Attempts to access them directly can cause undefined errors.

      • For convenience in this test, "requireHttps" is false. In production environments, set it to true. So that you see the delegated authorization process when you make a request, "requireLogin" has the default value true.

      • The target for storing authorization state information is ${attributes.openid}. This is where subsequent filters and handlers can find access tokens and user information.

  3. Test the setup:

    1. If you are logged in to AM, log out and clear any cookies.

    2. Go to http://openig.example.com:8080/home/id_token.

      The AM login page is displayed.

    3. Log in to AM as user george, password C0stanza, and then allow the application to access user information.

      The home page of the sample application is displayed.

Authenticating Automatically to the Sample Application

To authenticate automatically to the sample application, change the last name of the user george to match the password C0stanza, and add a StaticRequestFilter like the following to the end of the chain in 07-openid.json:

{
  "type": "StaticRequestFilter",
  "config": {
    "method": "POST",
    "uri": "http://app.example.com:8081/login",
    "form": {
      "username": [
        "${attributes.openid.user_info.sub}"
      ],
      "password": [
        "${attributes.openid.user_info.family_name}"
      ]
    }
  }
}

The StaticRequestFilter retrieves the username and password from the context, and replaces the original HTTP GET request with an HTTP POST login request containing credentials.

Read a different version of :