AM as OIDC provider
This page gives an example of how to set up AM as an OIDC provider and PingGateway 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. AM is the single, preregistered OIDC provider and PingGateway is the relying party:
Before you start, prepare AM, PingGateway, and the sample application as described in Example installation for this guide.
-
Set up AM as an OIDC provider:
-
Select Services > Add a Service and add a Validation Service with the following Valid goto URL Resources:
-
https://ig.example.com:8443/*
-
https://ig.example.com:8443/*?*
-
-
Create an OAuth 2.0 Authorization Server:
-
Select Services > Add a Service > OAuth2 Provider.
-
Add a service with the default values.
-
-
Create an OAuth 2.0 Client to request OAuth 2.0 access tokens:
-
Select Applications > OAuth 2.0 > Clients.
-
Add a client with the following values:
-
Client ID:
oidc_client
-
Client secret:
password
-
Redirection URIs:
https://ig.example.com:8443/home/id_token/callback
-
Scope(s):
openid
,profile
, andemail
-
-
(Optional) On the Core tab, switch to using a client secret associated with a secret label by setting a Secret Label Identifier and mapping the label to a secret.
To learn more, read Create a client profile and Map and rotate secrets in the AM documentation.
-
On the Advanced tab, select the following values:
-
Grant Types:
Authorization Code
-
-
-
-
Set up PingGateway:
-
Set up PingGateway for HTTPS, as described in Configure PingGateway for TLS (server-side).
-
Set an environment variable for
oidc_client
, and then restart PingGateway:$ export OIDC_SECRET_ID='cGFzc3dvcmQ='
-
Add the following route to PingGateway to serve the sample application .css and other static resources:
-
Linux
-
Windows
$HOME/.openig/config/routes/00-static-resources.json
%appdata%\OpenIG\config\routes\00-static-resources.json
{ "name" : "00-static-resources", "baseURI" : "http://app.example.com:8081", "condition": "${find(request.uri.path,'^/css') or matchesWithRegex(request.uri.path, '^/.*\\\\.ico$') or matchesWithRegex(request.uri.path, '^/.*\\\\.gif$')}", "handler": "ReverseProxyHandler" }
-
-
Add the following route to PingGateway:
-
Linux
-
Windows
$HOME/.openig/config/routes/07-openid.json
%appdata%\OpenIG\config\routes\07-openid.json
{ "name": "07-openid", "baseURI": "http://app.example.com:8081", "condition": "${find(request.uri.path, '^/home/id_token')}", "heap": [ { "name": "SystemAndEnvSecretStore-1", "type": "SystemAndEnvSecretStore" }, { "name": "AuthenticatedRegistrationHandler-1", "type": "Chain", "config": { "filters": [ { "name": "ClientSecretBasicAuthenticationFilter-1", "type": "ClientSecretBasicAuthenticationFilter", "config": { "clientId": "oidc_client", "clientSecretId": "oidc.secret.id", "secretsProvider": "SystemAndEnvSecretStore-1" } } ], "handler": "ForgeRockClientHandler" } } ], "handler": { "type": "Chain", "config": { "filters": [ { "name": "AuthorizationCodeOAuth2ClientFilter-1", "type": "AuthorizationCodeOAuth2ClientFilter", "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", "issuer": { "name": "Issuer", "type": "Issuer", "config": { "wellKnownEndpoint": "http://am.example.com:8088/openam/oauth2/.well-known/openid-configuration" } }, "scopes": [ "openid", "profile", "email" ], "authenticatedRegistrationHandler": "AuthenticatedRegistrationHandler-1" } } ], "requireHttps": false, "cacheExpiration": "disabled" } } ], "handler": "ReverseProxyHandler" } } }
For information about how to set up the PingGateway route in Studio, see OpenID Connect in Structured Editor.
Notice the following features about the route:
-
The route matches requests to
/home/id_token
. -
The
AuthorizationCodeOAuth2ClientFilter
enables PingGateway to act as a relying party. It uses a single client registration defined inline. -
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 (OIDC provider). This is why the redirect URI in the client profile in AM is set tohttps://ig.example.com:8443/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 agoto
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 valuetrue
. -
The target for storing authorization state information is
${attributes.openid}
. This is where subsequent filters and handlers can find access tokens and user information.
-
-
-
Test the setup:
-
In your browser’s privacy or incognito mode, go to https://ig.example.com:8443/home/id_token.
The AM login page is displayed.
-
Log in to AM as user
demo
, passwordCh4ng31t
, and then allow the application to access user information.The home page of the sample application is displayed.
-
Authenticate automatically to the sample application
To authenticate automatically to the sample application, change the last
name of the user demo
to match the password Ch4ng31t
, 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.