Login Quick Start: Android

The BindID service is an app-less, strong portable authenticator offered by Transmit Security. BindID uses FIDO-based biometrics for secure, convenient, and consistent passwordless authentication. This guide explains how to integrate BindID into your Android application—including the changes required for your login screen and application. Since BindID implements the OpenID Connect (OIDC) standard, the integration steps are similar to other OIDC-based services like Sign in with Google. Learn more about BindID

For an example integration, check out our Android Java sample application in GitHub.

Step 1: Configure Your Application

To integrate with BindID, you'll need to configure an application in the BindID Admin Portal (see Admin Portal: Get Started). You can either create a new application or use one that you already created.

From Applications, here is the basic client setup that is required for your application:

  • Set the allowed redirect URIs—Specify the URIs of your application to which users are allowed to be redirected after authentication (e.g., Acme://login-result). This URI will return to the mobile application with the result.
  • Get your BindID credentials—Obtain the client ID and client secret used to identify your mobile application to the BindID Service.

Step 2: Add SDK to Your Project

The latest version of the BindID Android SDK can be downloaded from this Maven repository. Add the SDK to your project so your application can access all the BindID functionality, as described below.

Add the following in the shared build.gradle file (“allprojects” scope):

...
allprojects {
...
repositories {
...
maven { url "file:///<Full path to uncompressed SDK bundle folder>" }
...
}
...

Add the following in the module build.gradle file (project scope):

...
dependencies {
...
compile ('com.ts:bindid:1.0.0@aar') { transitive=true }
...
}
...

Step 3: Configure the SDK

You need to configure the BindID SDK with your client ID, and to work with the BindID sandbox environment.

Add the following code to initialize the SDK:

XmBindIdSdk.getInstance().initialize(XmBindIdConfig.create(
applicationContext,
XmBindIdServerEnvironment.createWithMode(XmBindIdServerEnvironmentMode.Sandbox),
"[CLIENT_ID]"
)).addListener(object : ObservableFuture.Listener<Boolean, XmBindIdError> {
override fun onComplete(result: Boolean) {
Log.i("BID", "SDK Initialized")
}
override fun onReject(error: XmBindIdError) {
Log.e("BID", "SDK Initialize failed")
}
})

where [CLIENT_ID] should be replaced with your client ID configured in step 1.

Step 4: Set Up Redirection

Upon completing authentication, BindID redirects to a Redirect URI provided in step 1. This URI is a deep link that should return to your mobile application. To create a link to your application, add an intent filter to your app manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
<application>
...
<activity android:name="com.ts.bindid.BindIdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="[YOUR_HOST]"
android:scheme="[YOUR_SCHEME]" />
</intent-filter>
</activity>
...
</application>
</manifest>

where [YOUR_HOST] and [YOUR_SCHEME] should be replaced, resulting in a deep link that looks like [YOUR_SCHEME]://[YOUR_HOST] (e.g., Acme://login-result).

Step 5: Add Login to Your App

Add the code that will initiate the BindID login process by including a snippet like the one below in your login screen. This code will be used to authenticate the user, retrieve the user tokens using the authorization code (PKCE flow), and send the tokens to your backend. This example shows a client-side PKCE token exchange, however, BindID also supports a backend PKCE token exchange using the Token API.

fun authenticate() {
XmBindIdSdk.getInstance().authenticate(
XmBindIdAuthenticationRequest.create("[REDIRECT_URI]").apply {
this.usePkce = true
}).addListener(object : ObservableFuture.Listener<XmBindIdResponse, XmBindIdError> {
override fun onComplete(response: XmBindIdResponse) {
Log.i("BID", "Authentication successful")
exchange(response)
}
override fun onReject(error: XmBindIdError) {
handleError(error)
}
})
}
fun exchange(response: XmBindIdResponse) {
XmBindIdSdk.getInstance().exchangeToken(
XmBindIdExchangeTokenRequest.create(response)
).addListener(object :
ObservableFuture.Listener<XmBindIdExchangeTokenResponse, XmBindIdError> {
override fun onComplete(tokenResponse: XmBindIdExchangeTokenResponse) {
Log.i("BID", "Token exchange successful")
sendTokenToServer(tokenResponse.accessToken, tokenResponse.idToken)
}
override fun onReject(error: XmBindIdError) {
handleError(error)
}
})
}
fun sendTokenToServer(one: String, two: String) {
// Add code to send the ID and access token to your application server here
}
fun handleError(error: XmBindIdError) {
// Add code to process the authentication error here
}

where [REDIRECT_URI] is redirect URI you configured in step 1 and the deep link added in step 4.

The functions in the snippet above should be implemented as follows:

  • sendTokenToServer should send the ID and access tokens received upon successful authentication to your backend server, where it will be processed (see step 6).
  • handleError should respond to an authentication error, possibly by presenting a suitable message to the user.

Step 6: Handle User Token

The ID token received in step 5 contains various user information as claims. This user may either be already known to BindID, or a new user.

  • If the user is unknown to BindID, the ID token will not include the bindid_alias claim. The application should respond by taking the user through a registration process where the application establishes user identity (see step 7). Afterwards, the application should set a BindID alias for the user so that subsequent logins will be associated with it.
  • If the user is known to BindID, the ID token will include the bindid_alias claim. Your application should look up this value within its user-store to identify the application user to which this alias is registered, and use that user for the rest of the session.

Step 7: Register New User

If the ID token received in step 5 indicates the user is unknown to BindID, the application should:

  1. Validate the user’s identity. Your mobile application should run its existing authentication process to authenticate the user (e.g., using username and password). Whichever process you choose to run should establish the identity of the user in your mobile application. We recommend explaining to the user that you only need their username and password this time to enable Biometric Login.

  2. Define the BindID Alias for the user. The Alias is an identifier that BindID will return to your application every time the user completes a successful authentication process. Whether the alias is a new identifier you generate only for BindID purposes, or an existing internal user identifier that the application already uses, it must be unique for the user. You should not use the same Alias for different users of your application. NOTE: Consider that the ID token may be exposed to the client before passing sensitive information in the alias.

  3. Record that BindID Alias on the BindID service. To set the BindID Alias for the BindID user, your application server should send the following HTTP POST request:

    POST /session-feedback HTTP/1.1
    Host: api.bindid-sandbox.io
    Content-Type: application/json
    Authorization: BindIdBackend AccessToken [ACCESS_TOKEN]; [FEEDBACK_AUTH_VALUE]
    {
    "subject_session_at": [ACCESS_TOKEN],
    "reports": [
    {
    "type": "authentication_performed",
    "alias":[BINDID_ALIAS],
    "time": [AUTHENTICATION_TIME]
    }
    ]
    }
    TokenSubstitute with...
    [ACCESS_TOKEN]Access token received in step 5.
    [BINDID_ALIAS]BindID Alias to assign to the BindID user, as a string.
    [AUTHENTICATION_TIME]Time when the user was authenticated, expressed as the number of seconds since 1970-01-01 00:00. You can use the current time at the time of this request.
    [FEEDBACK_AUTH_VALUE]Token validating this request. This should be computed by the application server by computing HMAC-SHA256 over the [ACCESS-TOKEN] value, using the Client Secret obtained in step 1 as the secret. The HMAC-SHA256 computation result is then included encoded with Base64 encoding. See sample below.

    This sample Java code generates the [FEEDBACK_AUTH_VALUE] and constructs the Authorization header value:

    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.UnsupportedEncodingException;
    import java.nio.charset.StandardCharsets;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    public static String calculateAuthorizationHeaderValue(String clientSecret, String bindIdAccessToken) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
    // Create and initialize the Mac instance
    Mac mac = Mac.getInstance("HmacSHA256");
    byte[] keyBytes = clientSecret.getBytes(StandardCharsets.UTF_8);
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
    mac.init(keySpec);
    // Calculate the MAC on the BindID AccessToken
    byte[] signedBytes = mac.doFinal(bindIdAccessToken.getBytes(StandardCharsets.UTF_8));
    // Encode the signed bytes to base64
    String encodedResult = Base64.getEncoder().encodeToString(signedBytes);
    // Create the Authorization Header value
    return "BindIdBackend AccessToken " + bindIdAccessToken + "; " + encodedResult;
    }

Step 8: Test Your Integration

Once you complete your integration with BindID, test your integration as described below. Make sure to use a mobile device that has never been used to login with BindID, and that has Chrome browser installed (to support FIDO2 biometric authentication).

  1. Initiate a login process with BindID.
  2. A page with your logo will be displayed, which will ask for your email address. Enter your email address and submit.
  3. An approval screen is displayed. Click to Approve.
  4. You should receive a one-time code to your email address. Enter the code in the screen displayed in your mobile device.
  5. Run the biometric authentication process on the mobile device.
  6. The BindID process ends and returns to your application.
  7. Your application should run their authentication process if this is the first time the user runs BindID from your application.
  8. Initiate a new login process with BindID from the same device.
  9. This time the email collection screen, approval screen, and verification code screen should not be displayed.
  10. Run the biometric authentication process on the mobile device.
  11. The BindID process ends and returns to your application.