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.
-
In Xcode, in the Project Navigator, right-click your project, and then click Add Package Dependencies….
-
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. -
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.
-
Select the
PingJourneylibrary, and in the Add to Target column select the name of your project. -
Repeat the previous step for any other packages you want to use in your project.
-
Click Add Package.
Xcode displays the chosen packages and any prerequisites they might have in the Package Dependencies pane of the Project Navigator.
-
If you don’t already have CocoaPods, install the latest version.
-
If you don’t already have a Podfile, in a terminal window, run the following command to create a new Podfile:
pod init
-
Add the following lines to your Podfile:
pod 'PingJourney'
-
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:
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 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:
// 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():
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
trueto force traversal of an authentication journey, even if the user already has a valid session.Default is
false. - noSession
-
Set this parameter to
trueto 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.
// 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
}