Using the Reference Application
HYPR SDK for iOS
General Setup
All general SDK setup is handled in the AppDelegate.swift
class. As an SDK consumer, you can perform the following operations:
- Enable authenticators
- Set a push notifications provider
- Set a custom headers delegate
- Enable SSL pinning (recommended, but also should be enabled on server)
- Enable the AAID picker view controller
In the reference app project in the AppDelegate.swift
class, you can also check UI customization and other optional functionality.
internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Enable the authenticators
HYPRUAFClient.registerAuthenticatorModule(HYPRFingerprintAsm.self)
HYPRUAFClient.registerAuthenticatorModule(HYPRFaceIDAsm.self)
HYPRUAFClient.registerAuthenticatorModule(HYPRFaceAsm.self)
HYPRUAFClient.registerAuthenticatorModule(HYPRPINAsm.self)
HYPRUserAgent.initializeHYPRADP { (error) in
if error != nil {
print("ADP init error: \(error!)")
}
}
// Out of Band Authentication - Set the Push Notification Adapter (FirebaseAdapter by default)
HYPRUserAgent.setNotificationProviderAdapter(HYPRFirebaseAdapter.shared())
// Out of Band Authentication - Enable Push Notifications
HYPRFirebaseAdapter.shared().userPushNotifications(enabled: true)
// For sending/receiving HTTP Headers in HYPR SDK calls
HYPRUserAgent.setCustomHeadersDelegate(self)
// Enable or Disable SSL Pinning
HYPRUserAgent.setSSLPinningEnabled(false)
// Enable default AAID Picker UI for UserAgent
HYPRUserAgent.setAAIDPickerViewEnabled(true)
// Set AAIDPickerViewController
let viewController = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "PickerViewController")
HYPRUserAgent.setAAIDPickerViewController(viewController)
// Optional: Set the Face Authenticator Parameters
HYPRFaceAsm.setTimeout(60000)
return true
}
Setting UserAgent
Profiles
UserAgent
ProfilesThere are three view controllers:
ViewController.swift
to demonstrate FIDO-only use case, registration, and authenticationWebProfileViewController.swift
to demonstrate pairing and subsequent login with a web-based accountWorkstationProfileViewController.swift
to demonstrate pairing, unlock, and offline unlock with a workstation
They all have a similar setProfile
method. Here you must specify the rpAppId
(which corresponds to the desired rpAppId
in Control Center) and the relying party server URL.
private func setProfile() {
// Retrieve personaID. This value is unique per profile
let localPersonaId = UserDefaults.standard.value(forKey: WorkstationProfileViewController.wokrstationKey) as! String?
// Find the profile by personaID if it exists
let filteredProfiles = HYPRUserAgent.sharedInstance().profiles()?.filter({ (profile) -> Bool in
profile.persona?.personaId == localPersonaId
})
if localPersonaId != nil && filteredProfiles != nil && filteredProfiles!.count > 0 {
HYPRUserAgent.sharedInstance().switchActiveProfile(filteredProfiles![0])
// Otherwise create and register new profile
} else {
// Set the Authenticator UI Customizations
setAuthenticatorUICustomizations()
// Create the profile configuration where you specify the following:
let profileConfig = HYPRUserAgentProfileConfiguration(rpAppId: "RP App ID here: i.e. HYPRDefaultApplication",
rpServerUrl: "Place the RP URL here: i.e. https://9999-pov.hypr.com",
deviceType: "WORKSTATION",
rpSSLPinCredentials: nil,
additionalData: nil)
// Create the profile with the profile configuration
let profile = HYPRUserAgentProfile(displayName: "<Your profile name goes here>", configuration: profileConfig, persona: nil, userAccounts: nil, apiEndpoints: nil)
// Register it
HYPRUserAgent.sharedInstance().registerProfile(profile!)
if let personaId = HYPRUserAgent.sharedInstance().activeProfile()?.persona?.personaId {
UserDefaults.standard.set(personaId, forKey: WorkstationProfileViewController.wokrstationKey)
}
}
}
Setting ActionId
ActionId
To register/authenticate using a specific FIDO policy, you may specify each as an ActionID
. Passing nil
will call the default policy if one exists at your rpAppId
.
To register/authenticate in ViewController.swift
you must substitute your policy names for <Your policy name goes here>
for both registration and authentication.
@IBAction func registerNewUser(_ sender: UIButton) {
HYPRUserAgent.setDefaultAPIVersion(NSNumber(integerLiteral: 2))
guard HYPRUserAgent.sharedInstance().activeUserAccount() == nil else {
presentStatusAlert(title: "Registration", message: "You already registered a user either from Out of Band Device Setup or standard Registration")
return;
}
HYPRUserAgent.setParentViewController(self)
HYPRUserAgent.sharedInstance().registerUser(withName: nil, action: "<Your policy name goes here>", completion: { (error) in
if (error != nil) {
self.presentStatusAlert(title: "Registration", message: "There was an error registering the user: \(error?.localizedDescription ?? "")")
} else {
self.presentStatusAlert(title: "Registration", message: "User was successfully registered!")
}
})
}
@IBAction func authenticate(_ sender: UIButton) {
HYPRUserAgent.setDefaultAPIVersion(NSNumber(integerLiteral: 2))
HYPRUserAgent.setParentViewController(self)
HYPRUserAgent.sharedInstance().authenticateUser(nil, action: "<Your policy name goes here>", completion: { (error) in
if(error != nil) {
// Proces the authentication error:
self.presentStatusAlert(title: "Authentication", message: "There was an error authenticating the user \(error?.localizedDescription ?? "")")
}
else {
self.presentStatusAlert(title: "Authentication", message: "User was successfully authenticated!")
}
})
}
In WebProfileViewController.swift
you can register your workstation with a QR or with a PIN. Using a PIN you can specify the policy name as ActionID
instead of <Your policy goes here>
. If nil
is passed the default registration action
will be used.
@IBAction func addWebAccountQR(_ sender: Any) {
// // Uses information from QR Code to register the remote device
HYPRUserAgent.sharedInstance().registerRemoteDevice { (error) in
if(error != nil) {
self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
}
else {
self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
self.tableView.reloadData()
}
}
}
// Works with v3 api only
@IBAction func addWebAccountPIN(_ sender: Any) {
let userAccount = HYPRUserAgent.sharedInstance().activeUserAccount()
// if no userAccount exists and nil is passed as a userAccount parameter - the new userAccount will be created
// if pass nil to actionId parameter - the default policy will be used
HYPRUserAgent.sharedInstance().registerRemoteDevice(forUser: userAccount ?? nil, pinInputType: .alert, actionId: "<Your policy goes here>") { (error) in
if(error != nil) {
self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
}
else {
self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
self.tableView.reloadData()
}
}
}
In WebProfileViewController.swift
you can register your workstation with a QR or with a PIN. Using a PIN you can specify the policy name as ActionID
instead of <Your policy goes here>
. If nil
is passed the default registration action
will be used.
// If you are using this method, you don't need to setup the profile as descibed in setProfile() method
@IBAction func addWorkstationQR(_ sender: Any) {
// Uses information from QR Code to register the remote device
HYPRUserAgent.sharedInstance().registerRemoteDevice { (error) in
if(error != nil) {
self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
}
else {
self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
self.tableView.reloadData()
}
}
}
// Works with v3 api only
@IBAction func addWorkstationPIN(_ sender: Any) {
let userAccount = HYPRUserAgent.sharedInstance().activeUserAccount()
// if no userAccount exists and nil is passed as a userAccount parameter - the new userAccount will be created
// if pass nil to actionId parameter - the default policy will be used
HYPRUserAgent.sharedInstance().registerRemoteDevice(forUser: userAccount ?? nil, pinInputType: .alert, actionId: "<Your policy goes here>") { (error) in
if(error != nil) {
self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
}
else {
self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
self.tableView.reloadData()
}
}
}
Accept No Imitations
The web-based flow does not work on a simulator.
The above settings are the main settings of the HYPR SDK for iOS. Other optional settings can be found in the reference app classes.
App Screens
- FIDO-only flow:
- Workstation flow:
- Web flow:
Updated about 1 month ago