ForgeRock Identity Gateway (IG) Integration with the New ForgeRock Identity Cloud

Introduction

It’s exciting time here at ForgeRock. The ForgeRock Identity Cloud rapidly enables customers to embrace next generation IAM and realise return on investment quicker. For more on what this service offers check out the following links:

  • ForgeRock Identity Cloud overview here
  • ForgeRock Identity Cloud documentation here

In this exciting world, enabling customers to quickly and easily integrate with the ForgeRock Identity Cloud platform is critical. In this blog we’ll go through how to integrate ForgeRock Identity Gateway (IG) with ForgeRock Identity Cloud via a single script. Note you could also use this script for non ForgeRock Identity Cloud it’s just some of UI setup steps look a little different.

To learn more about IG check out this link for an overview and this link for product documentation.

Scenario

“As a new customer I want to understand IG through play and in particular how to configure IG to protect a sample application via Cross Domains Single Sign On (CDSSO) with the ForgeRock Identity Cloud.”

This is the specific scenario this blog addresses. To configure end-to-end you’ll need to be a ForgeRock Identity Cloud customer or be interested in this new offering, reach out here for more.

Back to the business at hand!

Script and Artefacts

The script and artefacts are located at this location. Here you’ll find the following:

  • install_ig_fidc.sh — core bash script for deploying IG and the Sample Application.
  • A set of admin.json.* files for configuring the connector ports for IG.
  • A set of route files which tell IG how to connect to and protect the Sample Application.

Components

The artefacts work together to create the following on the same target host:

  • An IG instance in what’s called Standalone mode on the target host. Standalone is pretty cool in that instead of having to deploy IG into a web container via a WAR file, IG can now just be downloaded via a zip file and fired up using ./startup.sh without container based deployment through the magic of Vert.x. For more check out the IG What’s New link here.
  • A Sample Application for IG to protect.
  • A set of routes for IG to protect the Sample Application via Cross Domain Single Sign On (CDSSO) with ForgeRock Identity Cloud.

Note that the end result will be a start position; additional configuring, tuning, hardening and all that production ready goodness will need to executed on top of this base.

Check out the README file for a list of pre-requisites and what needs to be configured in ForgeRock Identity Cloud.

The following section breaks down the script to describe what’s going on.

Environment Checks

The first thing the script does is check the target environment to ensure everything is “pukka”. The following is checked:

  • The IG ZIP file is present on the target filesystem.
  • The ForgeRock Sample App JAR file is present on the target filesystem.
  • The IG host FQDN is reachable.
  • The Sample App FQDN is reachable.
  • The target host can connect out to the ForgeRock Identity Cloud instance.
function envChecks() {
clear
echo "*********************"
#Check IG zip is present
if [ -f "$IG_BINARY_LOC" ]; then
echo "IG ZIP found at: $IG_BINARY_LOC continuing..."
else
echo "IG ZIP file not found. Please copy to $IG_BINARY_LOC"
echo "Exiting..."
exit 1
fi
#Check Sample JAR is present
if [ -f "$SAMPLE_BINARY_LOC" ]; then
echo "SAMPLE JAR file found at: $SAMPLE_BINARY_LOC continuing..."
else
echo "SAMPLE JAR file not found. Please copy to $SAMPLE_BINARY_LOC"
echo "Exiting..."
exit 1
fi
#Check IG host is reachable
if ping -q -c 1 -W 1 $IG_HOST >/dev/null; then
echo "IG host at $IG_HOST is reachable, continuing..."
else
echo "IG host not reachable at $IG_HOST"
echo "Check the /etc/hosts contains an entry for $IG_HOST mapped to the IP address of this machine"
echo "Exiting..."
exit 1
fi
#Check Sample host is reachable
if ping -q -c 1 -W 1 $SAMPLE_HOST >/dev/null; then
echo "Sample host at $SAMPLE_HOST is reachable, continuing..."
else
echo "Sample host not reachable at $SAMPLE_HOST"
echo "Check the /etc/hosts contains an entry for $SAMPLE_HOST mapped to the IP address of this machine"
echo "Exiting..."
exit 1
fi
#Check IG host can connect to FIDC AM
RESPONSE=`curl -sw '%{http_code}' -m 5 $AM_HOST`
if [ $RESPONSE = 302 ]; then
echo "FIDC AM reachable at $AM_HOST, continuing..."
else
echo "Unable to connect to ForgeRock AM here: $AM_HOST"
echo "Please resolve the connection issue before executing this script"
echo "Exiting..."
exit 1
fi
}

Installation Directory Check and Process Shutdown

Next the script checks if IG has already been deployed and if the IG and Sample App processes are running. If so these are cleaned up ready for a fresh install. This function looks like this:

function clean() {
echo "*********************"
if [ -d "$INSTALL_LOC" ]; then
echo "Existing IG found"
echo "Checking if IG is running"
if [ ! -z `ps x --no-header -o pid,cmd | awk '!/awk/&&/openig/{print $1}'` ]; then
echo "IG is running. Stopping..."
`ps x --no-header -o pid,cmd | awk '!/awk/&&/openig/{print $1}' | xargs -r kill`
sleep 5
echo "Done"
else
echo "IG is not running, continuing..."
fi
echo "Checking if Sample App is running"
if [ ! -z `ps x --no-header -o pid,cmd | awk '!/awk/&&/IG-sample/{print $1}'` ]; then
echo "Sample App is running. Stopping..."
`ps x --no-header -o pid,cmd | awk '!/awk/&&/IG-sample/{print $1}' | xargs -r kill`
sleep 5
echo "Done"
else
echo "Sample app is not running, continuing..."
fi
echo "Removing installation directory"
rm -rf $INSTALL_LOC
else
echo "Installation directory $INSTALL_LOC not found, continuing..."
fi
}

Deploy IG and Configure Ports

Now we’ve got the housekeeping out of the way the script moves into build mode and onto deploying IG and configuring ports. If http mode was selected at install, then IG will deploy just one connector on the HTTP port. If https mode was selected both a HTTP and HTTPS connector will be setup and self-signed certificates generated for the HTTPS connector. Note if HTTPS is used then its best practice to disable the HTTP connector, however in this instance as it’s for demo purposes we’re ok. These functions looks like this:

function DeployIG() {
echo "*********************"
echo "Extracting IG here $INSTALL_LOC"
mkdir -p $INSTALL_LOC $IG_CONFIG_LOC
cd $INSTALL_LOC
unzip -q $IG_BINARY_LOC
echo "Starting/Stopping IG to create folder structure"
nohup $IG_BIN_LOC/start.sh $IG_CONFIG_LOC &
sleep 5
`ps x --no-header -o pid,cmd | awk '!/awk/&&/openig/{print $1}' | xargs -r kill`
mkdir $IG_CONFIG_LOC/config
echo "Done"
}
function configurePorts() {
echo "*********************"
if [ $MODE == "http" ]; then
cd $IG_CONFIG_LOC
mkdir bin
echo "Creating admin.json file configured with HTTP PORT $IG_HTTP_PORT"
sed s,{HTTP_PORT},$IG_HTTP_PORT, $SCRIPT_LOC/admin.json.HTTP_ONLY > $IG_CONFIG_LOC/config/admin.json
echo "IG ports set and application deployed"
fi
if [ $MODE == "https" ]; then
cd $IG_CONFIG_LOC
mkdir secrets bin
echo "Generating Self-Signed certificate for HTTPS"
keytool \
-genkey \
-alias https-connector-key \
-keyalg RSA \
-keystore ./secrets/IG-keystore \
-storepass $KEYSTORE_STOREPASS \
-keypass $KEYSTORE_KEYPASS \
-dname "CN=$IG_HOST,O=Example Corp,C=FR"
echo -n $KEYSTORE_STOREPASS > ./secrets/keystore.pass
echo "export IG_KEYSTORE_DIRECTORY=$IG_CONFIG_LOC/secrets" > $IG_CONFIG_LOC/bin/env.sh
echo "Creating admin.json file configured with HTTP PORT $IG_HTTP_PORT and HTTPS PORT $IG_HTTPS_PORT"
sed -e s,{HTTP_PORT},$IG_HTTP_PORT, -e s,{HTTPS_PORT},$IG_HTTPS_PORT, $SCRIPT_LOC/admin.json.HTTP_and_HTTPS > $IG_CONFIG_LOC/config/admin.json
echo "IG ports set and application deployed"
fi
}

Deploy the ForgeRock Sample Application

Now we need to make IG do something useful by deploying an application it can proxy and protect. So next up the script deploys this sample application on your ports of choice (one HTTP and the other HTTPS). This function looks like this:

function deploySample() {
echo "*********************"
echo "Deploying Sample App for IG to protect on HTTP port $SAMPLE_HTTP_PORT and HTTPS port $SAMPLE_HTTPS_PORT"
mkdir -p $INSTALL_LOC/sample_app
cp $SAMPLE_BINARY_LOC $INSTALL_LOC/sample_app
echo "Starting sample app"
nohup java -jar $INSTALL_LOC/sample_app/IG-sample-application-7.0.1.jar $SAMPLE_HTTP_PORT $SAMPLE_HTTPS_PORT > $INSTALL_LOC/sample_app/console.log 2>&1&
echo "Done. Access the sample app at http://$SAMPLE_HOST:$SAMPLE_HTTP_PORT/home or https://$SAMPLE_HOST:$SAMPLE_HTTPS_PORT/home"
}

Deploy routes into IG

Are we there yet!? Nearly. This part is where the magic happens. Two routes are setup to tell IG about the Sample App, how to connect to it and how to protect it.

The first static-resources.json tells IG to act as a reverse proxy for the Sample App without protection for non critical data like CSS. This is a performance optimisation.

The second cdsso-idc.json tells IG to protect the /home/cdsso context of the Sample App. On access IG checks for the presence of an OIDC like id_token. If present and valid access is granted, if not the user-agent (browser) is re-directed to the ForgeRock Identity Cloud for user login. On successful login, the request is re-directed back to IG, it again checks for the presence and validity of the token and if all is well grants access.

The following diagram courtesy of the ForgeRock documentation here describes this interaction in more detail:

CDSSO flow between IG the Sample App and ForgeRock Identity Cloud.

This function looks like this:

function configureRoutes(){
echo "*********************"
mkdir $IG_CONFIG_LOC/config/routes
echo "Adding agent_secret to $IG_CONFIG_LOC/bin/env.sh for the routes to reference"
echo "export AGENT_SECRET_ID=$IG_AGENT_SECRET_B64" >> $IG_CONFIG_LOC/bin/env.sh
echo "Configuring routes from IG to the Sample App"
echo "Note IG will only interface with the HTTP port (port $SAMPLE_HTTP_PORT) of the Sample App"
echo "Configuring static route for Sample App CSS here: $SCRIPT_LOC/static-resources.json"
sed s,{BASE_URI},$BASE_URI, $SCRIPT_LOC/static-resources.json > $IG_CONFIG_LOC/config/routes/static-resources.json
echo "Configuring CDSSO route to protect the Sample App here: $SCRIPT_LOC/cdsso-idc.json"
sed -e s,{BASE_URI},$BASE_URI, -e s,{AM_HOST},$AM_HOST, -e s,{AM_REALM},$AM_REALM, -e s,{IG_AGENT_ID},$IG_AGENT_ID, -e s,{REDIRECT_URI},$SAMPLE_HOST_REDIRECT_URI, -e s,{JWK_URL},$AM_JWK_URL, $SCRIPT_LOC/cdsso-idc.json > $IG_CONFIG_LOC/config/routes/cdsso-idc.json
echo "Routes configured"
}

Fire it up!

Finally, IG is started up ready for action! This script looks like this:

function igStartup(){
echo "*********************"
echo "Configuring completed. Starting up IG using nohup to ensure the IG process remains active when the shell terminates"
echo "Logs are located here: $IG_CONFIG_LOG/log"
nohup $IG_BIN_LOC/start.sh $IG_CONFIG_LOC > $IG_CONFIG_LOC/logs/console.out 2>&1&
echo "Done"
echo "Access IG using http://$IG_HOST:$IG_HTTP_PORT/home/cdsso or if configured https://$IG_HOST:$IG_HTTPS_PORT/home/cdsso"
echo "If configuration was successful then the user should be redirected for login and on return be presented with the sample page."
}

Putting it all together

To execute, download/clone the Stash repo in your folder of choice and follow the README pre-reqs. When the script is executing with ./install_ig_fidc.sh httpor ./install_ig_fidc.sh https the following output is returned:

Execution output

If all is well with the world then accessing the IG address referenced at the bottom of the script (e.g. https://ig.test.com:9444/home/cdsso) will result in a redirect to ForgeRock Identity Cloud for login and then back again to return the following, Tada!

Sample Application Success Page

Conclusion

There you have it, a script to rapidly deploy IG to integrate with ForgeRock Identity Cloud. Hope this helps!

--

--

--

Technical Director / Distinguished IAM Technical Architect @ ForgeRock www.linkedin.com/in/darindershokar

Love podcasts or audiobooks? Learn on the go with our new app.

Common problems for layout elements in CSS — best practices

How to Use Scala’s Pattern Matching

120-days Docker Security Policy at Fidelity Investments

Placeholder calendar image

How to redeem a code for SalesForza.com

How to schedule Python script (cron) on AWS Elastic Beanstalk with Django context

My first encounter with SameSite attribute in cookies

Tutorial Series : No-Code Apps With Google AppSheet

Huawei P40 pro debloat Anleitung

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Darinder Shokar

Darinder Shokar

Technical Director / Distinguished IAM Technical Architect @ ForgeRock www.linkedin.com/in/darindershokar

More from Medium

Pre-deployment steps for TKG on AWS

Microservices: The Matrix and The Architect

Shoreline: Production Ops, Finally