Pass runtime data downstream in a JWT
This example sets up PingOne Advanced Identity Cloud as an identity provider, to pass identity or other runtime information downstream, in a JWT signed with a PEM.
For more information about using runtime data, refer to
Passing data along the chain. To help with development, the sample
application includes a /jwt
endpoint to display the JWT, verify its signature,
and decrypt it.
Before you start, prepare PingOne Advanced Identity Cloud, PingGateway, and the sample application as described in Example installation for this guide.
-
Set up secrets:
-
Locate a directory for secrets, and go to it:
$ cd /path/to/secrets
-
Create the following secret key and certificate pair as PEM files:
$ openssl req \ -newkey rsa:2048 \ -new \ -nodes \ -x509 \ -days 3650 \ -subj "/CN=ig.example.com/OU=example/O=com/L=fr/ST=fr/C=fr" \ -keyout ig.example.com-key.pem \ -out ig.example.com-certificate.pem
Two PEM files are created, one for the secret key, and another for the associated certificate.
-
Map the key and certificate to the same secret ID in PingGateway:
$ cat ig.example.com-key.pem ig.example.com-certificate.pem > key.manager.secret.id.pem
-
Generate PEM files to sign and verify the JWT:
$ openssl req \ -newkey rsa:2048 \ -new \ -nodes \ -x509 \ -days 3650 \ -subj "/CN=ig.example.com/OU=example/O=com/L=fr/ST=fr/C=fr" \ -keyout id.key.for.signing.jwt.pem \ -out id.key.for.verifying.jwt.pem
-
Make sure the following files have been added to your secrets directory:
-
id.key.for.signing.jwt.pem
-
id.key.for.verifying.jwt.pem
-
key.manager.secret.id.pem
-
ig.example.com-certificate.pem
-
ig.example.com-key.pem
-
-
-
Set up PingOne Advanced Identity Cloud:
-
Log in to the PingOne Advanced Identity Cloud admin UI as an administrator.
-
Go to Identities > Manage > Alpha realm - Users, and add a user with the following values:
-
Username:
demo
-
First name:
demo
-
Last name:
user
-
Email Address:
demo@example.com
-
Password:
Ch4ng3!t
-
-
Register a PingGateway agent with the following values, as described in Register a PingGateway agent in PingOne Advanced Identity Cloud:
-
ID:
ig_agent_jwt
-
Password:
password
-
Redirect URLs:
https://ig.example.com:8443/jwt/redirect
-
-
(Optional) Authenticate a PingGateway agent to PingOne Advanced Identity Cloud.
PingGateway agents are automatically authenticated to PingOne Advanced Identity Cloud by a deprecated authentication module in PingOne Advanced Identity Cloud. This step is currently optional, but will be required when authentication chains and modules are removed in a future release of PingOne Advanced Identity Cloud. -
Add a Validation Service:
-
In PingOne Advanced Identity Cloud, select Native Consoles > Access Management. The AM admin UI is displayed.
-
Select Services, and add a validation service with the following Valid goto URL Resources:
-
https://ig.example.com:8443/*
-
https://ig.example.com:8443/*?*
-
-
-
-
Set up PingGateway:
-
Set up TLS by adding the following file to PingGateway, replacing the value for the property
secretsDir
:-
Linux
-
Windows
$HOME/.openig/config/admin.json
%appdata%\OpenIG\config\admin.json
{ "mode": "DEVELOPMENT", "properties": { "secretsDir": "/path/to/secrets" }, "connectors": [ { "port": 8080 }, { "port": 8443, "tls": "ServerTlsOptions-1" } ], "session": { "cookie": { "sameSite": "none", "secure": true } }, "heap": [ { "name": "ServerTlsOptions-1", "type": "ServerTlsOptions", "config": { "keyManager": { "type": "SecretsKeyManager", "config": { "signingSecretId": "key.manager.secret.id", "secretsProvider": "ServerIdentityStore" } } } }, { "name": "ServerIdentityStore", "type": "FileSystemSecretStore", "config": { "format": "PLAIN", "directory": "&{secretsDir}", "suffix": ".pem", "mappings": [{ "secretId": "key.manager.secret.id", "format": { "type": "PemPropertyFormat" } }] } } ] }
-
-
Set an environment variable for the PingGateway agent password, and then restart PingGateway:
$ export AGENT_SECRET_ID='cGFzc3dvcmQ='
The password is retrieved by a SystemAndEnvSecretStore, and must be base64-encoded.
-
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, replacing the value for the properties
secretsDir
andamInstanceUrl
:-
Linux
-
Windows
$HOME/.openig/config/routes/jwt-idc.json
%appdata%\OpenIG\config\routes\jwt-idc.json
{ "name": "jwt-idc", "condition": "${find(request.uri.path, '/jwt')}", "baseURI": "http://app.example.com:8081", "properties": { "secretsDir": "/path/to/secrets", "amInstanceUrl": "https://myTenant.forgeblocks.com/am" }, "heap": [ { "name": "SystemAndEnvSecretStore-1", "type": "SystemAndEnvSecretStore" }, { "name": "AmService-1", "type": "AmService", "config": { "url": "&{amInstanceUrl}", "realm": "/alpha", "agent": { "username": "ig_agent_jwt", "passwordSecretId": "agent.secret.id" }, "secretsProvider": "SystemAndEnvSecretStore-1", "sessionCache": { "enabled": false } } }, { "name": "pemPropertyFormat", "type": "PemPropertyFormat" }, { "name": "FileSystemSecretStore-1", "type": "FileSystemSecretStore", "config": { "format": "PLAIN", "directory": "&{secretsDir}", "suffix": ".pem", "mappings": [{ "secretId": "id.key.for.signing.jwt", "format": "pemPropertyFormat" }] } } ], "handler": { "type": "Chain", "config": { "filters": [ { "name": "CrossDomainSingleSignOnFilter-1", "type": "CrossDomainSingleSignOnFilter", "config": { "redirectEndpoint": "/jwt/redirect", "authCookie": { "path": "/jwt", "name": "ig-token-cookie" }, "amService": "AmService-1" } }, { "name": "UserProfileFilter", "type": "UserProfileFilter", "config": { "username": "${contexts.ssoToken.info.uid}", "userProfileService": { "type": "UserProfileService", "config": { "amService": "AmService-1" } } } }, { "name": "JwtBuilderFilter-1", "type": "JwtBuilderFilter", "config": { "template": { "name": "${contexts.userProfile.commonName}", "email": "${contexts.userProfile.rawInfo.mail[0]}" }, "secretsProvider": "FileSystemSecretStore-1", "signature": { "secretId": "id.key.for.signing.jwt", "algorithm": "RS512" } } }, { "name": "HeaderFilter-1", "type": "HeaderFilter", "config": { "messageType": "REQUEST", "add": { "x-openig-user": ["${contexts.jwtBuilder.value}"] } } } ], "handler": "ReverseProxyHandler" } } }
-
-
-
Test the setup:
-
Go to https://ig.example.com:8443/jwt.
If you receive warnings that the site is not secure, respond to the warnings to access the site. The PingOne Advanced Identity Cloud login page is displayed.
-
Log in to PingOne Advanced Identity Cloud as user
demo
, passwordCh4ng3!t
. The sample app displays the signed JWT along with its header and payload. -
In
USE PEM FILE
, enter the absolute path toid.key.for.verifying.jwt.pem
to verify the JWT signature.
-