Getting Login Credentials From AM
Use IG with AM's password capture and replay to bring SSO to legacy web applications, without the need to edit, upgrade, or recode. This feature helps you to integrate legacy web applications with other applications using the same user identity.
For an alternative configuration using an AM policy agent instead of IG's CapturedUserPasswordFilter, see the documentation for earlier versions of IG.
The following figure illustrates the flow of requests when an unauthenticated user accesses a protected application. After authenticating with AM, the user is logged into the application with the username and password from the AM login session.
IG intercepts the browser's HTTP GET request.
Because the user is not authenticated, the SingleSignOnFilter redirects the user to AM for authentication.
AM authenticates the user, capturing the login credentials, and storing the encrypted password in the user's AM session.
AM redirects the browser back to the protected application.
IG intercepts the browser's HTTP GET request again:
The user is now authenticated, so IG's SingleSignOnFilter passes the request to the CapturedUserPasswordFilter.
The CapturedUserPasswordFilter checks that the SessionInfoContext
${contexts.amSession.properties.sunIdentityUserPassword}
is available and notnull
. It then decrypts the password and stores it in the CapturedUserPasswordContext, at${contexts.capturedPassword}
.
The PasswordReplayFilter uses the username and decrypted password in the context to replace the request with an HTTP POST of the login form.
The sample application validates the credentials.
The sample application responds with the user's profile page.
IG then passes the response from the sample application to the browser.
Before you start, prepare AM, IG, and the sample application as described in "Example Installation for This Guide".
Generate an AES 256-bit key:
$
openssl rand -base64 32
loH...UFQ=
Set up AM:
(For AM 6.5.x and earlier versions) Select Identities > demo, and set the demo user password to
Ch4ng31t
.(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/*?*
Select Applications > Agents > Identity Gateway, add an agent with the following values:
Agent ID:
ig_agent
Password:
password
Leave all other values as default.
Select Applications > Agents > Java (or J2EE).
Add an agent with the following values:
Agent ID:
ig_agent
Agent URL:
http://openig.example.com:8080/agentapp
Server URL:
http://openam.example.com:8088/openam
Password:
password
On the Global tab, deselect Agent Configuration Change Notification.
This option stops IG from being notified about agent configuration changes in AM, because they are not required by IG.
Update the Authentication Post Processing Classes for password replay:
Select Authentication > Settings > Post Authentication Processing.
In Authentication Post Processing Classes, add
com.sun.identity.authentication.spi.JwtReplayPassword
.
Add the AES 256-bit key to AM:
Select DEPLOYMENT > Servers, and then select the AM server name,
http://openam.example.com:8088/openam
.In earlier version of AM, select Configuration > Servers and Sites.
Select Advanced, and add the following property:
PROPERTY NAME:
com.sun.am.replaypasswd.key
PROPERTY VALUE: The value of the AES 256-bit key from step 1.
Select Configure > Global Services > Platform, and add
example.com
as an AM cookie domain.By default, AM sets host-based cookies. After authentication with AM, requests can be redirected to AM instead of to the resource.
Set up IG:
Set environment variables for the value of the AES 256-bit key in step 1, and the IG agent password, and then restart IG:
$
export AES_KEY='AES 256-bit key'
$export AGENT_SECRET_ID='cGFzc3dvcmQ='
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" }
Add the following route to IG:
$HOME/.openig/config/routes/04-replay.json
%appdata%\OpenIG\config\routes\04-replay.json
{ "name": "04-replay", "condition": "${matches(request.uri.path, '^/replay')}", "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/" } }, { "name": "CapturedUserPasswordFilter", "type": "CapturedUserPasswordFilter", "config": { "ssoToken": "${contexts.ssoToken.value}", "keySecretId": "aes.key", "keyType": "AES", "secretsProvider": "SystemAndEnvSecretStore-1", "amService": "AmService-1" } } ], "handler": { "type": "Chain", "config": { "filters": [ { "type": "SingleSignOnFilter", "config": { "amService": "AmService-1" } }, { "type": "PasswordReplayFilter", "config": { "loginPage": "${true}", "credentials": "CapturedUserPasswordFilter", "request": { "method": "POST", "uri": "http://app.example.com:8081/login", "form": { "username": [ "${contexts.ssoToken.info.uid}" ], "password": [ "${contexts.capturedPassword.value}" ] } } } } ], "handler": "ReverseProxyHandler" } } }
Notice the following features of the route:
The route matches requests to
/replay
.The agent password for AmService is provided by a SystemAndEnvSecretStore in the heap.
If the request does not have a valid AM session cookie, the SingleSignOnFilter redirects the request to AM for authentication.
After authentication, the SingleSignOnFilter passes the request to the next filter, storing the cookie value in an
SsoTokenContext
.The PasswordReplayFilter uses the CapturedUserPasswordFilter declared in the heap to retrieve the AM password from AM session properties. The CapturedUserPasswordFilter uses the AES 256-bit key to decrypt the password, and then makes it available in a CapturedUserPasswordContext.
The value of the AES 256-bit key is provided by the SystemAndEnvSecretStore.
The PasswordReplayFilter retrieves the username and password from the context. It replaces the browser's original HTTP GET request with an HTTP POST login request containing the credentials to authenticate to the sample application.
Test the setup:
If you are logged in to AM, log out.
Go to http://openig.example.com:8080/replay. The SingleSignOnFilter redirects the request to AM for authentication.
Log in to AM as user
demo
, passwordCh4ng31t
. The request is redirected to the sample application.