Integrate authentication widget for strong MFA
This topic describes how to integrate the authentication widget along with OIDC Authorization PKCE grant into the mobile app using the Android SDK
Provide an authentication and authorization flow with strong MFA and self-service registration by embedding the authentication widget into the SDK's Android mobile app.
Prerequisites
Step 1: Setup the OpenID connect custom app
Step 2: Create authentication rule
Create an authentication rule that challenges the user to authenticate with MFA when the mobile app requests it. Refer to the following link for steps and instructions for creating an authentication rule in the Admin Portal.
https://docs.cyberark.com/Product-Doc/OnlineHelp/Idaptive/Latest/en/Content/CoreServices/Authenticate/MFA-AdminPortal.htm
To find your authentication Policies in the Admin Portal, navigate Core Services > Policies > Authentication Policy. Refer to the following figures for an example.


Step 3: Configure authentication Widget:
Please refer to https://docs.cyberark.com/Product-Doc/OnlineHelp/idaptive/Latest/en/Content/Widgets/Create-Authentication-Widget.htm to get information on how to use widgets
To find your authentication widgets in the Admin Portal, navigate to Web apps > Widgets. Refer to the following figures for an example.
Link the OIDC app with the authentication widget
How it works?
Integrate authentication widget with mobile app
The authentication client must have a configuration to interact with the CyberArk Identity Server. The Android app redirects the user to Authentication Widget 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.
Step 1: Create a builder object as shown below:
val cyberArkAccountBuilder = CyberArkAccountBuilder.Builder()
.systemURL(context.getString(R.string.cyberark_auth_system_url))
.hostURL(context.getString(R.string.cyberark_auth_host_url))
.clientId(context.getString(R.string.cyberark_auth_client_id))
.appId(context.getString(R.string.cyberark_auth_app_id))
.responseType(context.getString(R.string.cyberark_auth_response_type))
.scope(context.getString(R.string.cyberark_auth_scope))
.state(context.getString(R.string.cyberark_auth_state))
.redirectUri(context.getString(R.string.cyberark_auth_redirect_uri))
.build()
val cyberArkAccountBuilder = CyberArkAuthWidgetBuilder.Builder()
.systemURL(systemUrl.toString())
.hostURL(widgetHostUrl.toString())
.widgetId(widgetId.toString())
.resourceURL(resourceUrl.toString())
.build()
Step 2: Set up a view model and start the authentication widget flow
Use the CyberArkAuthProvider class, and the CyberArkAccountBuilder, CyberArkAuthWidgetBuilder parameters to set up a view model and start the authentication widget flow. The start authentication widget flow pattern is as follows:
val authResponseHandler: LiveData<ResponseHandler<String>> =
CyberArkAuthProvider.authWidgetLogin(cyberArkAccountBuilder)
.start(this, cyberArkAuthWidgetBuilder)
Authentication widget response handler
authWidgetResponseHandler.observe(this, {
when (it.status) {
ResponseStatus.SUCCESS -> {// Initiate authorize endpoint
}
ResponseStatus.ERROR -> {
}
ResponseStatus.LOADING -> {
}
}
})
Step 3: Set up a view model and initiate authorize endpoint
Use the CyberArkAuthProvider class, and the CyberArkAccountBuilder parameter to set up a view model and start the authorization endpoint. The start authorization endpoint flow pattern is as follows:
val authResponseHandler: LiveData<ResponseHandler<AuthCodeFlowModel>> =
CyberArkAuthProvider.login(cyberArkAccountBuilder).start(this)
Step 4: Declare the observer instance that will receive the authentication result
authResponseHandler.observe(this, {
when (it.status) {
ResponseStatus.SUCCESS -> {
// Save access token, refresh token and Id token in Shared Preference using keystore encryption
}
ResponseStatus.ERROR -> {
}
ResponseStatus.LOADING -> {
}
}
})
Step 5: Launch the authentication widget 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.

Step 6: Use device storage for access, refresh, and ID tokens
Save the access token, refresh token, and ID 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)
KeyStoreProvider.get().saveIdToken(it.data!!.id_token)
Step 7: 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)
Step 8: Refresh the 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.
Step 9: Obtain User Info from the ID token
An ID token is an artifact that confirms that the user has been authenticated. An ID Token is a JWT Token, which is a cryptographically signed Base64-encoded JSON object. Here is an example of the decoded ID token
ID Token Payload:
{
"auth_time": <authentication_time>,
"is": "<issuer_identifier>",
"given_name": "<user_name>",
"iat": <ID_token_issued_time>,
"aud": "<audience_this_ID_token_is_intended_for>",
"name": "<user_name>",
"email": "<user_email_address>",
"family_name": "<user_name>",
"preferred_username": "<user_name>",
"unique_name": "<user_name>",
"exp": <ID_token_expiry_time>,
"sub": "<An_identifier_for_user>",
"email_verified":
}
Step 10: Retrieve User Info using the Access token
Use the CyberArkAuthProvider class, and the CyberArkAccountBuilder parameter to set up a view model and start the retrieve user info flow. The retrieve user info flow pattern is as follows:
val authResponseHandler: LiveData<ResponseHandler<UserInfoModel>> =
CyberArkAuthProvider.userInfo(cyberArkAccountBuilder)
.start(this, accessTokenData)
Updated 9 months ago