How to write your very own ForgeRock Push Authenticator

Jonathan Knight
7 min readMay 24, 2019

--

Registering for push notifications.

The ForgeRock Identity Platform has provided push notification as an authentication factor for quite some time, making it easy for organisations to add this simple and user-friendly authentication method to their user journeys. But for push notification to a device, you need an app to handle the notification and allow the user to send a response. Fortunately, ForgeRock provides the ForgeRock Authenticator app, available to download for free from all leading app stores. However, most consumer facing organisations already have, or are in the process of developing, their own apps, so it makes much more sense to handle the push notifications there. This article covers the steps on how to embed this feature into your own apps, and includes a sample IOS project to help you get started.

Before you can even begin to think about writing a client app to handle push notifications, you first need to figure out how to create the sending service, application signing keys, and various other configuration. So before going any further I’d strongly recommend you first read this article by Steffo Weber: https://medium.com/@steffoweber/customizing-the-forgerock-authenticator-8b4cb23e7b8a

OK, so you’ve got your push service setup — let’s tackle the app. There are two flows that we need to implement, registration, allowing you to associate devices with a user id on a ForgeRock AM service, and authentication, handling a push notification sent to a registered device for the user to approve or reject. Registration involves the exchange of various data, including a shared secret, REST endpoints, and a challenge, encoded in QR format. To handle registration, the client app needs to scan the QR code, extract the data, and respond to the challenge by POSTing to the REST endpoint with a challenge response, encrypted using the mutual secret. The authentication flow is similar, essentially an encrypted response to a challenge, and the user’s accept or reject decision.

In the sample app I’ve packaged up all interaction for both flows in a class called “FRPushUtils”. This handles the data encodings, the challenge responses, and interaction with the AM push service. All that’s needed above and beyond this is a simple bit of user UI and some AV code to capture a QR code. Thankfully Apple and IOS makes that fairly trivial.

If you’re not starting with the sample app, then we’ll assume you have the basics of an app already prepared, with all the code signing and properties needed for the app to receive push notifications. Be sure to also include a copy of the FRPushUtils from the sample project. If you are starting with the sample app, be sure to change the bundle ID to match the ID you’ve associated with your push service — the bundle ID is what Apple uses to route messages to apps.

Step 1. — Prepare the app to handle push notifications

Since our app will be dealing with incoming push notifications, there are a few steps we need to cover to set this up. There are plenty of guides online which you can browse to understand this in detail, but for simplicity I’ll summarise them here.

In your AppDelegate.swift file add the following before the main AppDelegate class:

When the app first launches it will retrieve and store the device’s unique SNS push notification device ID. This will be needed later during the registration step with ForgeRock AM.

Next, add or update the ‘didFinishLaunchWithOptions’ function as follows:

Then add the following new functions which take care of asking the user for permission to handle push notifications:

Notice that the SNS device ID is stored on successfully registering to receive push notifications.

Finally, add a function to handle new incoming notifications. The main job of this is to pass the incoming message payload to a function to display an alert to the user. We’ll come to that later:

Step 2. — CommonCrypto

Both registration and authentication flows involve encryption of a challenge using a shared secret, so we need access to IOS standard crypto functions. Since these aren’t available by default in Swift we need to setup a bridging header in order to use the objective C methods:

Create/add a new header file (.h) to your project with the following code:

Then in your projects settings, go to Build Settings, scroll down to Swift Compiler — General and add your bridging header:

Step 3. — JWT and JSON support

A couple of useful external libraries make handling JWT and JSON objects a lot simpler. Add the following cocoa pods to your project Podfile (use ‘pod init’ to create a new Podfile if needed):

Then go ahead and run ‘pod install’ to install them (remember, once you’re using cocoa pods, you’ll from now on need to open your XCode project by clicking the .xcworkspace file rather than the .xcodeproj file).

Step 4. — adding some UI

For the registration flow we need to scan a QR code presented by ForgeRock AM. Assuming your app has a suitable ViewController available, you need add support to use the device’s camera, and a delegate function to handle QR recognition:

Then add a simple “Register” button to your storyboard, and wire it to a function like this:

This sets up video capture, displays a preview of the capture, and most importantly, tells IOS to start searching for QR code.

Now add the delegate function which will be called by the AV system to handle a found QR code. In this function we halt the video preview and call the FRPushUtils.registerWithQRCode function with arguments containing the found QR code, the device’s SNS device ID (stored in Step …), and some success/failure handlers to feedback the result to the user. For now we don’t really care whether registration was successful or not, so we just alert the user with the result.

Now we need some code to handle an incoming notification, prompt the user for an accept/reject response, and send the response back to ForgeRock AM. The following two functions take care of this:

Step 5. — Permission to use the camera.

One final step before we’re ready to build, apps need to get permission from the use in order to access the device’s camera. For this, browse the project’s Info.plist resource and add a new key for “Privacy — Camera Usage Description”. Set it to something descriptive such as “To take profile photo and scan QR codes”:

Step 6. — Compile and enjoy

That’s it — compile and run this and you should have the basics of an app to handle registration and authentication flows using ForgeRock AM push notification.

Besides making it look pretty, there’s a couple of other things you might want to consider enhancing:

  • In its current form the app can only handle registration to a single AM deployment for a single user id. That’s probably fine for the most use cases, but there’s no reason why it couldn’t be extended to become a generic authenticator (similar to the ForgeRock Authenticator) for multiple different accounts on different AM services.
  • The app doesn’t use any local security for the flows. In most cases you might want to add something like FaceID, or TouchID, or a PIN, before letting the user approve or deny an authentication request.
  • The app doesn’t record a log of pending requests, nor previously handled requests. Generally, authentication notifications have a short timeout period (defined by AM) so there’s little benefit in letting them “queue up” on the client, but there’s no reason why you couldn’t handle this if the use case warranted. But in any case, it might be useful to store a log of previous requests, so the user can see missed, approved, or rejected authentications.

In the next article we’ll explore using an adapted version of the default ForgeRock AM push authentication node, one which can send additional payload data along with the request. This could enable an app to provide more contextual details to the user about the request, for example, geolocation info to show to origin of the authentication, or transaction data, to show details of a payment needing user approval, or details of a call center agent asking for approval to call a customer.

--

--