Add authentication and authorization using OIDC protocol

This topic describes how to integrate the authentication and authorization flow using the OIDC Authorization code with PKCE grant into the mobile app using the iOS SDK

Integrate the authentication and authorization flow using the OIDC Authorization code with PKCE grant into your mobile app using the Android SDK.

As prerequisites, setup the OpenID connect custom app

📘

The Redirect URI for OpenID connect should be "{auth_scheme}://{auth_host}/iOS/{YOUR_APP_PACKAGE_NAME}/redirectURICallback"

How it works?

856

Integrate the OIDC flow using the iOS SDK

Step 1: Import the CyberArk Identity SDK

import Identity

Step 2: Use the below code snippet to configure the account:

guard let config = plistValues(bundle: Bundle.main) else { return }
            //CyberarkAccount
            guard let account =  CyberArkAuthProvider.webAuth()?
                    .set(clientId: config.clientId)
                    .set(domain: config.domain)
                    .set(redirectUri: config.redirectUri)
                    .set(applicationID: config.applicationID)
                    .set(presentingViewController: self)
                    .setCustomParam(key: "", value: "")
                    .set(scope: config.scope)
                    .set(webType: .sfsafari)
                    .set(systemURL: config.systemurl)
                    .build() else { return }
            CyberArkAuthProvider.login(account: account)

Step 3: Define a callback to receive the access token as a result of step 2 on successful authentication.

//This method should be called either in viewDidLoad() or 
//anywhere else before calling the login method in the step 2.
func addObserver(){
        CyberArkAuthProvider.didReceiveAccessToken = { (status, message, response) in
            if status {
                DispatchQueue.main.async {
                    self.dismiss(animated: true) {
                        self.save(response: response)
             						// Navigate to the required screen.
                      }
                }
            } else {
              // Handle errors here if any.
            }
        }
    }

Step 4: Save the access and refresh tokens to secure storage (for example Keychain)

Save the access and refresh tokens to secured storage, one of the best ways is Keychain Sharing. To implement Keychain Sharing, refer to the following steps:

  1. Goto Xcode, select the root project >> target >> Signing & Capabilities
  2. Click on + Capability  and double click on the Keychain sharing option to add the capability to the project if it is not added.
  3. Use the following code snippet to store the tokens in the Keychain.
2672
func save(response: AccessToken?) {
        do {
            if let accessToken = response?.access_token {
                try KeyChainWrapper.standard.save(key: KeyChainStorageKeys.accessToken.rawValue, data: accessToken.toData() ?? Data())
            }
            if let refreshToken = response?.refresh_token {
             try KeyChainWrapper.standard.save(key: KeyChainStorageKeys.refreshToken.rawValue, data: refreshToken.toData() ?? Data())
            }
            if let expiresIn = response?.expires_in {
              let date = Date().epirationDate(with: expiresIn)
                try KeyChainWrapper.standard.save(key: KeyChainStorageKeys.access_token_expiresIn.rawValue, data: Data.init(from: date))
            }
        } catch {
           // Handle errors here
        }
    }

Step 5: Handle the response returned during the Login

It is required to handle the response received from the internal browser(Safari Controller), there should be a call back to handle the response in the app when the user is redirected to the app.

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

        for context in URLContexts {
            do {
                process(with: context.url)
            } catch let error {
                //Handle error here
            }
        }
    }
func process(with url: URL) {
        CyberArkAuthProvider.resume(url: url)
    }