Android SDK

Enable your mobile app with CyberArk's multifactor authentication.

Introduction

CyberArk Identity Android SDK provides an authentication framework that enables you to implement CyberArk's advanced multi-factor authentication (MFA) services within your mobile app.
Using the SDK, you can integrate a rich set of authentication factors, such as QR Code authentication and push authentication, providing the best possible security and user experience for your end users.

Prerequisites

Before you begin this tutorial, make sure you have created a CyberArk Free Trial account to view your tenant details. You need a tenant ID and tenant URL to:

  • Register your Android app in CyberArk Identity.
  • Redirect your app to CyberArk Identity with a set of authentication challenges for end users signing in using an Android app.

    The Identity Android SDK package handles all of the interactions with CyberArk Identity to provide a secure and trusted login flow.

CyberArk Identity automatically generates a tenant URL for each (tenant) account by prefixing tenant ID to tenant URL. For example mytenant is your tenant ID in mytenant.my.idaptive.app tenant URL. To find your tenant details in the Admin Portal, navigate to Settings > Customization > Login > Tenant URLs. Refer to the following figure for an example.

The Admin Portal also lets you configure the authorization code flow for your Android app to receive an Access Token and ID token or Refresh Token.

The tenant URL that Identity Service generates is also known as system URL. You need a system URL to redirect your Android app when a user must authenticate.

The supplied code samples in this tutorial are written in Kotlin programming language.

Configure CyberArk as OAuth2 Identity provider

In order to utilize CyberArk Identity, you need to set up an OAuth2 Client in the Admin Portal so that your app can receive Access Token and ID token or Refresh Token from the OAuth2 Client after an authorization grant from CyberArk Identity.

For steps and instructions creating an OAuth 2.0 Client application in Admin Portal, refer to
Client Credentials Flow.

If you are developing a public app such as a mobile app, where client secret is not secure, recommended Authorization Code Flow with PKCE. For this, you select List (Apps > Web Apps > OAuth2 Client > General Usage > List) and add Allowed Clients.

Integrate the Identity Android SDK to your project

This section explains how to include the Identity Android SDK in your Android app so that you can call Identity APIs for a secure login flow.

Download Identity Android SDK package

A copy of the Identity Android SDK package (.aar) file is available on GitHub. You can download your copy and manually import it into your project. Click here to start download Identity Android SDK.

Import Identity Android SDK package to your project

Manually import the downloaded SDK package in your project for integration. To import the SDK package, copy the package and paste it into your Project > app > libs, as shown below.

After you import the SDK package, start Gradle sync.

Declare Gradle Implementation dependencies

When you use Gradle to build your app for Android, you must declare the Identity SDK dependencies so that Gradle can download all the required dependencies. Add the following in your app/build.gradle.

implementation files('libs/identitylibrary-release.aar') 
implementation "androidx.preference:preference-ktx:1.1.1"
  
//In-build unit test framework libs
testImplementation 'androidx.test:core:1.4.0'
testImplementation "androidx.arch.core:core-testing:2.1.0"
testImplementation "com.android.support.test:monitor:1.0.2"
  
//In-build android test framework libs
androidTestImplementation('androidx.test.espresso:espresso-intents:3.4.0')
  
//External test framework libs
testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.9'
testImplementation 'org.powermock:powermock-classloading-xstream:2.0.9'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.9'
testImplementation 'org.robolectric:robolectric:4.6.1'
testImplementation 'net.bytebuddy:byte-buddy:1.11.15'
testImplementation "org.json:json:20210307"
testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
  
//mockito should be at 3.2.4 for java 11
testImplementation 'org.mockito:mockito-core:3.9.0'
  
//"powermock-classloading-xstream" lib is dependent on "com.thoughtworks.xstream" lib to handle Snyk scan issues
implementation 'com.thoughtworks.xstream:xstream:1.4.18'
  
//"org.robolectric:robolectric" lib is dependent on "com.google.guava:guava" lib to handle Snyk scan issues
implementation 'com.google.guava:guava:30.1.1-android'
  
//LifeCycle libs
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
  
//Custom tab support browser plugin
implementation "androidx.browser:browser:1.3.0"
  
//Biometrics support libs
implementation "androidx.biometric:biometric:1.2.0-alpha03"  
  
//Retrofit network libs
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
  
//External libs
implementation('com.journeyapps:zxing-android-embedded:4.2.0') { transitive = false }
implementation 'com.google.zxing:core:3.4.1'
implementation 'pub.devrel:easypermissions:3.0.0'

Supported SDK version

The minimum supported Android SDK version is API level 24 and above to run this Identity SDK.

compileSdkVersion 31
buildToolsVersion "30.0.3"

defaultConfig {
    applicationId "com.cyberark.mfa"
    minSdkVersion 24
    targetSdkVersion 31
    versionCode 1
    versionName "1.0"
  }

Use Java 8 language features

The Identity Android SDK requires Java 8 language feature support. To enable Java 8 support for Android and Kotlin plugins respectively, add the following compile options in your build.gradle file in your app folder.

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8' 
    }

Add permission in AndroidManifest.xml

Open your app's AndroidManifest.xml file and add the following permission.

To perform actions on the token, you need to add the INTERNET permission to your AndroidManifest.xml file.

<manifest. >
<uses-permission android:name="android.permission.INTERNET" />
</manifest. >

Read values from config.xml

Create a string (config.xml) resource file that is referenced using the value provided in the name attribute.
Create a config.xml (Identity-demo-android > res > config.xml) and add the following resources.

<resources>
    <string name="cyberark_account_system_url">{YOUR_SYSTEM_URL}</string>
    <string name="cyberark_account_host_url">{YOUR_HOST_URL}</string>
    <string name="cyberark_account_client_id">{YOUR_CLIENT_ID}</string>
    <string name="cyberark_account_app_id">{YOUR_APP_ID}</string>
    <string name="cyberark_account_response_type">code</string>
    <string name="cyberark_account_scope">All</string>
    <string name="cyberark_account_redirect_uri">demo://{YOUR_HOST_NAME}/android/{YOUR_APP_PACKAGE_NAME}/callback</string>
    <string name="cyberark_account_scheme">demo</string>
</resources>

Replace {YOUR_APP_PACKAGE_NAME} with your actual application's package name.

demo://{YOUR_HOST_NAME}/android/{YOUR_APP_PACKAGE_NAME}/callback

Next, define the Manifest Placeholders for the CyberArk Identity Host and CyberArk Identity Scheme which are going to be used internally by the library to register an intent-filter. Go to your app/build.gradle file and add the manifestPlaceholders line as shown below:

android {
    defaultConfig {
        manifestPlaceholders = [cyberarkIdentityHost: "@string/cyberark_account_host_url",
                                cyberarkIdentityScheme: "@string/cyberark_account_scheme"]
    }

Resources

Parameter

Description

system_url

Your tenant URL. This is provided when you register your Android app.

host

The authorization server where your tenant is hosted.

client_id

An ID that Identifies your app in CyberArk Identity. This is provided when you register your app as a client.

app_id

A unique key is used to build the OAuth2 endpoint URL.

response_type

The type of response requested from the authorization server. This must be set to code for authorization code flow.

scope

The specific scopes that are being requested.

redirect_uri

The URL that a user is directed to after successful authentication.

scheme

The custom scheme implemented for redirection.

Start the authorization flow

First, the authentication client must have a configuration to interact with CyberArk Identity Server. The Android app redirects the user to CyberArk Identity for authentication. To request authorization, the Android app must redirect the user (browser) to make a secure HTTP call to the authorization endpoint with the following parameters. Create a builder object as shown here:

val cyberArkAccountBuilder = CyberArkAccountBuilder.Builder()
    .systemURL(getString(R.string.cyberark_account_system_url))
    .hostURL(getString(R.string.cyberark_account_host_url))
    .clientId(getString(R.string.cyberark_account_client_id))
    .appId(getString(R.string.cyberark_account_app_id))
    .responseType(getString(R.string.cyberark_account_response_type))
    .scope(getString(R.string.cyberark_account_scope))
    .redirectUri(getString(R.string.cyberark_account_redirect_uri))
    .build()

Set up a view model and start the authentication code flow using the CyberArkAuthProvider class, and the CyberArkAccountBuilder parameter. The start authentication code flow pattern is as follows:

val authResponseHandler: LiveData<ResponseHandler<AuthCodeFlowModel>> =
                CyberArkAuthProvider.login(cyberArkAccountBuilder).start(this)

Declare the observer instance that will receive the authentication result.

authResponseHandler.observe(this, {
          when (it.status) {
              ResponseStatus.SUCCESS -> {
              }
              ResponseStatus.ERROR -> {
              }
              ResponseStatus.LOADING -> {
              }
          }
    })

Launch the authorized URL in a Custom Tab

The Identity Android SDK is enabled with the ability to open the CyberArk Identity sign-in web page to perform the user authentication in a browser window.

  • After authentication, the app redirects the user back to the app to exchange the received authorization code for an access token and/or refresh token.

Use device storage for access and refresh token

Save the access token and/or refresh token in device storage (SharedPreference) using Keystore encryption.
The Keystore encryption model is as follows:

KeyStoreProvider.get().saveAuthToken(it.data!!.access_token)
KeyStoreProvider.get().saveRefreshToken(it.data!!.refresh_token)

Verify token expiry from the access token

Decode the access token to get the expiry time of the token. The following code sample validates and returns the status of the existing access token.

val status = JWTUtils.isAccessTokenExpired(accessTokenData)

Refresh token

Use the refresh token to obtain a new access token.

val refreshTokenResponseHandler: LiveData<ResponseHandler<RefreshTokenModel>> =
    CyberArkAuthProvider.refreshToken(cyberArkAccountBuilder).start(this, refreshTokenData)

Refer to Refresh Token for details.

Verify your Android device

The Identity Android SDK is enabled with an enrollment model that verifies an Android device. The enrollment model allows you to build your Android app with the ability to enroll new devices when a QR code or biometric option is used in the login flow. The enrollment model is as follows:

val authResponseHandler: LiveData<ResponseHandler<EnrollmentModel>> =
      CyberArkAuthProvider.enroll().start(this, accessTokenData)

Sign in to Identity Cloud by scanning a QR Code

The Identity Android SDK is enabled with the ability to present a highly secured and thrusted Multi-factor authentication (MFA) to your Android app. The QR code authentication mechanism allows a call to the authentication (tokens) endpoints by scanning a QR code using your Android device. Use the following procedure to register your new device for a Multi-factor Authentication.

Register your Android app for use with MFA

You can enable your Android app to securely verify user identity by using a mobile device as a second-factor authentication, an extra security step to the authentication process. After the user signs in, you provide the option to opt-in for a QR code Authenticator option before signing in to CyberArk Identity. Refer to the following steps for the authentication flow:

  1. Select QR code Authenticator on the Android device.
  1. Allow the built-in camera app to open.
  2. Open your organization's Sign In page.
  3. Point the camera at the QR Code.
  4. Scan QR code graphic on the Sign In page from your mobile app.
  • This allows SDK functions to call authentication endpoints using the scanned data and the received access token; CyberArk Identity verifies and authenticates the end-user.

Implement QR code Authenticator flow using CyberArkQRCodeLoginActivity class. The QR code login model is as follows:

// Start QR Code authenticator Activity
private fun startQRCodeAuthenticator() {
    val intent = Intent(this, CyberArkQRCodeLoginActivity::class.java)
    intent.putExtra("access_token", accessTokenData)
    startForResult.launch(intent)
} 
// Callback to handle QR Code Authenticator result
private val startForResult =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            // Use key "QR_CODE_AUTH_RESULT" to receive result data
            val data = result.data?.getStringExtra("QR_CODE_AUTH_RESULT")
            // Show QR Code Authenticator result using Toast
            Toast.makeText(
                this,
                data.toString(),
                Toast.LENGTH_LONG
            ).show()
        }
    }

Advanced biometric authentication

The Identity Android SDK is enabled with the ability to deliver biometric identity services with advanced biometric data processing. The biometric identity service enables your Android app to more securely confirm the identities for a seamless user sign in flow. Authentication can be enabled during the initial setup with device registration. To register a device:

  • Invoke strong biometric authentication dialog at app startup.
  • Invoke strong biometric authentication dialog when the access token expires.

Invoke Biometric utility instance

In order to register biometric, use the following code sample:

var cyberArkBiometricPromptUtility = CyberArkBiometricManager().getBiometricUtility(biometricCallback)

Show biometric options

The following code sample shows all the strong biometric options available on your device.

cyberArkBiometricPromptUtility.showBioAuthentication(this, null, "Use App Pin", false)

To start the service, register a biometric authentication callback using the CyberArkBiometricCallback interface. The biometric call model is as follows.

private val biometricCallback = object : CyberArkBiometricCallback {
           override fun isAuthenticationSuccess(success: Boolean) {
           }
           override fun passwordAuthenticationSelected() {
           }
           override fun showErrorMessage(message: String) {
           }
           override fun isHardwareSupported(boolean: Boolean) {
           }
           override fun isSdkVersionSupported(boolean: Boolean) {
           }
           override fun isBiometricEnrolled(boolean: Boolean) {
           }
           override fun biometricErrorSecurityUpdateRequired() {
           }
   }

Show available biometric authentication options

The following code snippet demonstrates how to implement biometric authentication for the first time. Use the code below as a reference.

var bioMetric = CyberArkBiometricManager().getBiometricUtility(biometricCallback)
/*Show all the strong biometric authentication options on prompt*/
  bioMetric.showBioAuthentication (this, null, "Use App Pin", false)

Logout client session from the browser

Call the end-session endpoint from the CyberArk Identity to clear the access token from your custom tab browser using the CyberArkAuthProvider class and the CyberArkAccountBuilder parameter. The logout model is as follows:

CyberArkAuthProvider.endSession(cyberArkAccountBuilder).start(this)

Remove access token and refresh token from device storage (SharedPreference)
using CyberArkPreferenceUtil class.

CyberArkPreferenceUtil.remove(Constants.ACCESS_TOKEN)
    CyberArkPreferenceUtil.remove(Constants.ACCESS_TOKEN_IV)
    CyberArkPreferenceUtil.remove(Constants.REFRESH_TOKEN)
    CyberArkPreferenceUtil.remove(Constants.REFRESH_TOKEN_IV)