Orchestration SDKs

Completing backchannel authentication transactions on iOS

PingOne Advanced Identity Cloud PingAM iOS

A federation service that starts a backchannel authentication transaction on behalf of your user receives a backchannel transaction URI from PingOne Advanced Identity Cloud or PingAM, and is responsible for forwarding that URI to your app, for example over a push notification, a deep link, or another transport of your choosing.

The backchannel URI carries the details of the transaction as query parameters, for example:

https://openam-forgerock-sdks.forgeblocks.com/am/UI/Login?realm=%2Falpha&authIndexType=transaction&authIndexValue=1bb31b1d-6b5f-4d5f-9a2f-6a6a7f6a2b3e

Use the Journey module’s start(backchannelUri:configure:) method to complete the transaction on receipt of the URI.

The method extracts the transaction details from the backchannel transaction URI and drives the associated journey to completion, just like the standard start() method described in Starting an authentication journey on iOS.

Step 1. Installing the Journey module

To install the Journey module for iOS, use Swift Package Manager (SPM) or CocoaPods to add the dependency to your project.

  • SPM (Swift Package Manager)

  • CocoaPods

You can install packages by using SPM (Swift Package Manager) on the iOS project.

  1. In Xcode, in the Project Navigator, right-click your project, and then click Add Package Dependencies…​.

  2. In the Search or Enter Package URL field, enter the URL of the repo containing the Orchestration SDK for iOS, https://github.com/ForgeRock/ping-ios-sdk.git.

  3. In Add to Project, select the name of your project, and then click Add Package.

    Xcode shows a dialog containing the libraries available for iOS.

  4. Select the PingJourney library, and in the Add to Target column select the name of your project.

  5. Repeat the previous step for any other packages you want to use in your project.

  6. Click Add Package.

    Xcode displays the chosen packages and any prerequisites they might have in the Package Dependencies pane of the Project Navigator.

  1. If you don’t already have CocoaPods, install the latest version.

  2. If you don’t already have a Podfile, in a terminal window, run the following command to create a new Podfile:

    pod init
  3. Add the following lines to your Podfile:

    pod 'PingJourney'
  4. Run the following command to install pods:

    pod install

Step 2. Configuring the Journey module

Import PingJourney, then call Journey.createJourney(), providing the Advanced Identity Cloud or PingAM server you want to target:

Configuring the Journey module
import PingJourney

let journey = Journey.createJourney { config in
    config.serverUrl = "https://openam-forgerock-sdks.forgeblocks.com/am"
    config.realm = "alpha"
    config.cookie = "ch15fefc5407912"
}

For the full range of configuration options available, see Configuring the Journey module on iOS.

The Orchestration SDK uses the serverUrl and realm you provide when configuring Journey, rather than the host or realm parameter encoded in the backchannel transaction URI.

This means a malicious or malformed backchannel transaction URI cannot redirect the SDK to contact a different server.

Step 3. Completing a journey using a backchannel transaction URI

Pass the backchannel transaction URI to start(backchannelUri:configure:) to start the journey the server configured for the transaction:

Starting a journey from a backchannel transaction URI on iOS
// backchannelUri is the value your app received from the federation service.
let node = await journey.start(backchannelUri: backchannelUri)

You can optionally apply parameters to start():

Adding parameters when starting a journey from a backchannel transaction URI
let node = await journey.start(backchannelUri: backchannelUri) { options in
    options.forceAuth = true
    options.noSession = true
}

The parameters you might use in the start(backchannelUri:configure:) method includes the following:

forceAuth

Set this parameter to true to force traversal of an authentication journey, even if the user already has a valid session.

Default is false.

noSession

Set this parameter to true to prevent the authentication journey from issuing a new session token upon successful completion.

Default is false.

Handle the returned node in exactly the same way as any other journey, as described in Navigating an authentication journey on iOS. A transaction that has expired, was already completed, or wasn’t found returns an ErrorNode carrying the server’s message.

Starting a journey and handling the returned node on iOS
// backchannelUri is the value your app received from the federation service.
let node = await journey.start(backchannelUri: backchannelUri)

switch node {
case let continueNode as ContinueNode:
    // Provide input to any callbacks in the journey, such as a username and password
    continueNode.callbacks.forEach { callback in
        switch callback {
        case let nameCallback as NameCallback:
            nameCallback.name = "demo"
        case let passwordCallback as PasswordCallback:
            passwordCallback.password = "5tr0ngP@S5w0rd!!"
        default:
            break
        }
    }

    // Proceed to the next node with the provided input
    let nextNode = await continueNode.next()

case let errorNode as ErrorNode:
    // Handle server-side errors, such as an expired or already-completed transaction
    print("Transaction error: \(errorNode.message)")

case let failureNode as FailureNode:
    // Handle unexpected errors, such as network issues or a missing JourneyConfig
    print("Failure: \(failureNode.cause)")

case let successNode as SuccessNode:
    // Authentication successful, retrieve the session
    let session = successNode.session

default:
    break
}