Integrating IG with Identity Cloud

Introduction

It's an exciting time here at ForgeRock. The ForgeRock Identity Cloud helps customers rapidly embrace next generation IAM, and quickly realize a return on their investment. 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, helping customers quickly and easily integrate with the ForgeRock Identity Cloud platform is critical. In this article, we’ll show you 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; 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 Domain Single Sign-On (CDSSO) with the ForgeRock Identity Cloud."

This is the specific scenario this article addresses. To configure this from end-to-end, you'll need to be a ForgeRock Identity Cloud customer, or be interested in it. Reach out here for more.

Back to the business at hand!

Script and artifacts

Find the script and artifacts at this location. Here, you'll find the following:

  • install_ig_fidc.sh, a 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 and protect the Sample Application.

Components

The artifacts 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 a 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 be executed on top of this base.

Check out the README file for a list of prerequisites 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:
xfunction 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 that we've got the housekeeping out of the way, the script moves into build mode, and on to 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 an HTTP and HTTPS connectors will be set up, and self-signed certificates generated for the HTTPS connector. Note that if HTTPS is used, then it's a 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"
fiif [ $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.passecho "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 set up 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 optimization.

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 redirected to the Identity Cloud for user login. On successful login, the request is redirected back to IG. It again checks for the presence and validity of the token. If all is well, access is granted.

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

image|0x0



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 and 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."
}

Put it all together

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

image|0x0

If all is well with the world, then accessing the IG address referenced at the bottom of the script (https://ig.test.com:9444/home/cdsso) will result in a redirect to 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!

More by this author



1 Like