Combining Ping Federate with ForgeRock AM for MFA

Patryk Krolikowski
12 min readApr 5, 2024

--

Why?

PingFederate (PF) and ForgeRock Access Management (AM) are both great and flexible products. They complement each other in different ways. There are certain use cases where having these two working together would provide lots of value. One such use case is around MFA, particularly in regulated markets or cross-border scenarios. Eg.:

  • You have a self-managed Ping Federate (PF) installation and cannot use Ping MFA cloud service (e.g. because your company prohibits the use of cloud solutions).
  • You operate a Ping Federate solution in mainland China, and using Ping MFA is not an option as it might not be reliably accessible via the great firewall.

In both cases, you can leverage AM’s journeys for an MFA solution to cope with a non-ideal world. AM is widely known for its Journeys (aka Trees) and many supported OOTB MFA methods such as OTP (email/SMS), OATH, or WebAuthN (Fido2). The difficulty or inconvenience lies in that AM was not originally designed to be integrated with a 3rd party access management product on that level.

In this article, we show how that can be achieved. In short, we can say there are two major use cases:

  • Use case 1 — Integrating identity repository;
  • Use case 2 — Developing Journeys and integrating them into the PingFederate flow;

So, the goal is to have an integrated solution that shares the identity data repository and provides rich MFA capabilities without relying on cloud services.

What?

We’ll cover the following:

From the high-level architecture perspective the “before” and “after” states would look like this:

After going through the configurations described below we will be able to achieve the following:

  • Create a user account in PingFederate that would be readily available in AM and vice versa — create a user account in AM that can be consumed by PingFederate
  • Configure MFA — for the article Push Authentication via a Mobile App in the AM Journey
  • Access resources protected by PingFederate embedding the newly configured MFA capability into the flow

We used the following product versions:

  • PingFederate 12.0.1.0
  • PingDirectory 10.0.0.2
  • ForgeRock Access Management: 7.4

and used OpenJDK 11 across the platform.

NOTE: Please note that as of April 2024, Ping Directory is not officially supported by AM. Ping is currently testing the combination of both products. On the other hand, Ping Federate is targeted to officially support the ForgeRock Directory Server later this year — so stay tuned!

How?

Preparations and assumptions

We assume you:

  • know how to install all of the products mentioned above,
  • have a basic understanding of PingFederate, AM, and PingDirectory
  • know how AM’s Journeys work and can create simple Journeys

That being said, here are some of the installation-related details, to give you a better understanding of what we did.

For the completeness of the exercise, we decided to run both Ping Federate and ForgeRock Access Management over HTTPS. You might need to apply some extra configuration to the application container.

AM

For instance, we ran AM on Tomcat and used a keystore file as the certificate source. We also had a PKCS12 formatted certificate but wanted to use JKS. Hence, the following conversion needed to happen:

keytool -importkeystore -srckeystore mypfxfile.pfx\
-srcstoretype pkcs12 -destkeystore clientcert.jks -deststoretype JKS

Then we could use the resulting clientcert.jks in Tomcat’s config (server.xml):

<Connector
port="8443"
protocol="HTTP/1.1"
SSLEnabled="true"
maxThreads="150"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
keystoreFile="/home/ec2-user/[your_keystore].jks"
keystorePass="[yourpass]"
/>

Of course, your particular config can be a bit different, but the above is just to illustrate what changes might be necessary.

Then we deployed AM using the AM Configurator Tool, which can be downloaded here (a Backstage account is required).

The Configurator used the following config (we called the file holding it config.pro):

SERVER_URL=https://am.meyademo.com:8443
DEPLOYMENT_URI=/am
BASE_DIR=/opt/am/am/amConfig
locale=en_US
PLATFORM_LOCALE=en_US
ADMIN_PWD=[YOUR_PASSWORD]
AMLDAPUSERPASSWD=[YOUR_PASSWORD]
COOKIE_DOMAIN=meyademo.com
ACCEPT_LICENSES=true
DATA_STORE=embedded
DIRECTORY_SERVER=am.meyademo.com
DIRECTORY_PORT=51636
DIRECTORY_SSL=SSL
DIRECTORY_ADMIN_PORT=54444
DIRECTORY_JMX_PORT=55555
ROOT_SUFFIX=dc=openam,dc=forgerock,dc=org
DS_DIRMGRDN=uid=admin
DS_DIRMGRPASSWD=[YOUR_PASSWORD]

Please make sure the DIRECTORY_SERVER value is an FQDN that is resolvable. It is also recommended not to use localhost.

Once the file is ready, Tomcat is running and the AM “war” file is deployed you can run the configurator like this:

java -jar openam-configurator-tool-14.1.3.21.jar — file config.pro

You might notice we used the DATA_STORE=embedded. This is a temporary configuration we wanted to use for simplicity reasons - to ensure we have a working standalone AM deployment. Keep reading ….

If everything goes fine we should be able to log into the root realm of AM using the administrative UI:

Use case 1 — Shared identity repository

Configure ForgeRock AM

Upon the first login into the admin interface, you will need to create a new realm:

We will call it pf:

Now, let’s set up PingDirectory as an Identity store. Click on “Identity Store” on the left menu. Remove the “embedded” one, and then click on “Add Identity Store”:

Select a name for your identity store (eg. PingDriectory), use “OpenDJ” in the “Type” dropdown and create the config:

We will use the following configuration in the next screen (you should change this config according to your PingDirectory settings):

Check “Load Schema” in the bottom right and click “Save Changes”. Now change to “Persistent Search Controls”, set your base dn as Persistent Search Base DN and save the config:

Let’s check the configuration by selecting “Identities” on the left-hand side menu and checking whether the identities inside PingDirectory are visible in the AM admin console:

You can try to create a new Identity in ForgeRock AM, but that will fail because we need to tweak the schema in PingDirectore, i.e., we must import a specific objectclass schema with a modified syntax.

Manual schema update in PingDirectory

Log in to the PingDirectory admin console and select LDAP schema in the left menu:

Now click on “Schema Utilities” -> “Import Schema Element”:

Use the following code and click on “Import”:

dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( 1.3.6.1.4.1.36733.2.2.1.14 NAME 'boundDevices' DESC 'Bound Device JSON data' SYNTAX 1.3.6.1.4.1.30221.2.3.4 X-ORIGIN 'OpenAM' )
-
add: objectClasses
objectClasses: ( 1.3.6.1.4.1.36733.2.2.2.14 NAME 'boundDevicesContainer' DESC 'Class containing bound device' SUP top AUXILIARY MAY ( boundDevices ) X-ORIGIN 'OpenAM' )
-

At this point, we’re done with PingDirectory and AM integration at the data layer level.

Now, we should be able to create a new user in AM. You can check this, by going back to the ForgeRock AM Admin console, selecting “Identities” -> “Add Identity” and creating a test user:

The user should be visible in the identity list:

Next, we will set up the PingFederate <-> AM integration.

Use case 2 — Developing Journeys and integrating them into the Ping Federate flow

In Use Case 2 we’re building on top of Use Case 1, combining Journeys with Ping Federate. In order to do that we need a few building blocks:

  1. ForgeRock Intelligent Access Integration Kit for Ping Federate
  2. A Journey created in AM
  3. Sample landing page

Setup ForgeRock Intelligent Access Integration Kit

You can find the kit here and the docs here.

Here’s what you need to do if you don’t like reading the docs.

  1. Download the Forgerock Intelligent Access Integration Kit .zip archive from the Ping Identity Integration Directory.
  2. Stop PingFederate.
  3. If you’re upgrading an existing deployment, back up your customizations and delete earlier versions of the integration files:
  • Delete the pf-forgerock-intelligent-access-adapter-<version>.jar file from your <pf_install>/pingfederate/server/default/deploy directory.

4. Extract the .zip archive and merge the contents of the dist directory with your <pf_install>/pingfederate directory.

5. If there is more than one version of the pf-authn-api-sdk-<version>.jar file in your <pf_install>/pingfederate/server/default/lib directory, delete all but the latest version of the file.

6. Start PingFederate.

7. If you operate PingFederate in a cluster, repeat steps 2–6 for each engine node.

8. Setup Ping Federate IdP Adapter — read on!

9. Setup a Policy in Ping Federate that makes use of the adapter — read on as well!

Setup Ping Federate IdP Adapter

Let’s focus on step “8” from the above. Here’s what you need to do:

Log in to the PingFederate Admin Console, select “IdP Adapters” and then select “Create New Instance”:

Use the following configuration on the “Type” tab and click “Next”.

In the next tab fill in your AM configuration data like BASEURL, REALM, and the JOURNEY name you want to use (we will use “Login” and create this journey later on).

Add Journey Response Mappings:

and click on “Next”.

In the “Extended Contract” step add mail and sn:

These will be used later in the Policy Configuration step.

Click “Next” in the “Adapter Attributes”. Select uid as a unique user key attribute, and select “Pseudonym” in the uid row.

Click on “Next” and leave the rest of the settings as defaults, clicking on the “Next” button. The summary page should look like this:

Setup Ping Federate Policy

With this, the adapter part is ready.

In the authentication step, let’s create a PingFederate policy and configure it to use the ForgeRock AM Adapter.

Click on “Policies” in the left menu and click on “Add policy”:

Use the following settings in the next step — select the ForgeRock Adapter we had configured and the contract we had set up:

Now, we need to take care of the Contract Mapping.

Select “Contract Mapping”:

then, on the “Attribute Sources & User Lookup” page, click “Next” and you should land on the “Contract Fulfillment” tab. Fill it in accordingly using the previously configured adapter as the “Source” and match it with the appropriate values:

Leave the “Issuance Criteria” as is and click Done. Save the Policy.

After saving the policy, it should show up in your policy list:

Click on the “Arrow up” button next to the newly created policy to move it up and make it the first on the list.

Create a basic login journey in AM

In the last step, we must set up an authentication journey in AM. Let’s call it “Login”. You are free to decide how simple or complex the journey should be.

We’ll start with something very basic — just a simple login flow. Then, we’ll extend the Journey to make it more useful and cover the MFA scenario we mentioned at the beginning of the article.

Roll up your sleeves and let’s get cracking!

First login to your ForgeRock Admin Console, then select “Authentication” -> “Trees” on the left menu and click “Create Tree”:

Call it “Login” and click on “Create”. You should end up with an empty journey. Let’s build something like this:

Now, we need to detour and explain one important thing briefly. By default users created in the Ping Directory lack a lot of AM-specific object classes. These classes are essential for more complex functions like MFA, WebAuthN, and more to work. That is why we need to ensure these classes are dynamically added to users when traversing the Journey.

For that, we’ll use a Scripted Decision Node to run a really simple script.

So, let’s head to the “Scripts” menu in the Realm and create a new script -> “New Script”.

We will call it AddObjectClassToUser, select the appropriate type for it and use “Next Generation” as the evaluator version:

and paste the following script into the script editor in the next step:

var username = nodeState.get(“username”);
// Get identity separately
var identity = idRepository.getIdentity(username);
// Set the attribute directly on the identity object
identity.setAttribute("objectClass", ["boundDevicesContainer","devicePrintProfilesContainer","deviceProfilesContainer","forgerock-am-dashboard-service","inetOrgPerson","inetuser","iplanet-am-auth-configuration-service","iplanet-am-managed-person","iplanet-am-user-service","iPlanetPreferences","kbaInfoContainer","oathDeviceProfilesContainer","organizationalPerson","person","pushDeviceProfilesContainer","sunAMAuthAccountLockout","sunFMSAML2NameIdentifier","top","webauthnDeviceProfilesContainer"]);
// Add some error handling
try {
// Explicitly persist data
// throws an exception if setAttribute failed
identity.store();
action.goTo("true");
} catch(e) {
logger.error("Unable to persist attribute. " + e);
action.goTo("false");
}

Save the changes:

Let’s go back to the Login journey we had created and let’s set it up like this:

Where the Scripted Decision Node is configured like this:

Lastly, we will tell AM we want to land on a specific URL once the Journey is successful. We’ll use the “Success URL” node for that:

With Success URL pointing at the landing page. In our case, it is:

https://[your_ping_federate]:9031/idp/startSSO.ping?PartnerSpId=decoder%3Apingidentity%3Acloud

Save the Journey.

Now, we’re ready to test everything. We can do this by navigating to an SSO-enabled SP in PingFederate.

We will use a Ping Test SAML SP with the following URL: https://[your_ping_federate]:9031/idp/startSSO.ping?PartnerSpId=decoder%3Apingidentity%3Acloud

The AM login interface should pop up:

After logging in with valid credentials, the Test SAML SP should pop up:

Extend the Journey and add MFA

Finally, it is time for something real. In this last step, we will add Push MFA functionality into the journey. We’ll leverage ForgeRock Authenticator App installed on a mobile device and the corresponding nodes:

  • Push Registration
  • Push Sender
  • Push Result Verifier Node
  • Push Wait Node

You will also need to create two services on the “realm” level in the Services section:

  • ForgeRock Authenticator (Push) service
  • Push Notification service (this one relies on AWS SNS)

We’ll leave the configuration of these nodes and services to you. It should be really easy — have a look at the docs!

Now, extend the journey to look like this:

Save it and retest the journey.

The MFA registration step should show up:

On your mobile device:

  1. Open ForgeRock Authenticator app
  2. Scan the QR code and accept the Push:

Now you should have your MFA onboarded:

And land on the test application page as before.

Summary

As you can see it is easy to integrate PingFederate, Ping Directory, and ForgeRock Access Management. It opens up many use cases, such as leveraging the orchestration capabilities of Journeys, integrations with a range of MFA methods, and adding IDM capabilities (provisioning, user lifecycle management, governance), just to name a few.

Charge your mouse and keyboard and start experimenting with unlocked use cases!

This article was a team effort — Aydin Tekin, Mehmet Yaliman, and me :-)

--

--

No responses yet