Skip to content

Android: Authentication

Authenticate an existing Passkey with the Service.

Get started by initializing the AssertionApi with an OkHttpClient and CookieJar.

val httpClient = OkHttpClient.Builder()
.cookieJar(cookieJar) // Use Cookie jar to share cookies between requests
.build()
val assertionApi = AssertionApi(httpClient)

👤 User Agent

The User-Agent string is used to authenticate the device.

// UA used to authenticate the device
val userAgent = "${BuildConfig.APPLICATION_ID}/${BuildConfig.VERSION_NAME} " +
"(Android ${Build.VERSION.RELEASE}; ${Build.MODEL}; ${Build.BRAND})"

🧮 Options

Fetch assertion options from the service.

val response = assertionApi.postAssertionOptions(
origin, // Origin Server
userAgent, // Required for checking the authenticator fingerprint
credentialId // Base64URL Encoded Credential ID
).await()

🎉 Retrieving

There are several ways to handle the retrieval of an existing Passkey. We recommend using the FIDO2ApiClient or CredentialManager

MainActivity.kt
val fido2Client = Fido2ApiClient(context)
val origin = "https://my-liquid-service.com"
val credentialId = "Base64URL Encoded Credential ID"
// Fetch Attestation Options
val response = attestationApi.postAssertionOptions(origin, userAgent, credentialId).await()
// Parse the response to PublicKeyCredentialRequestOptions
val publicKeyCredentialRequestOptions = response.body.toPublicKeyCredentialRequestOptions()
// Activity Result Handler
fun handleAuthenticatorAssertionResult(activityResult: ActivityResult){
val bytes = activityResult.data?.getByteArrayExtra(Fido.FIDO2_KEY_CREDENTIAL_EXTRA)
when {
activityResult.resultCode != Activity.RESULT_OK ->
Log.d(TAG, "Not OK!")
bytes == null ->
Log.e(TAG, "Error!")
else -> {
/**
* Handle the PublicKeyCredential
*
* Now you can combine the PublicKeyCredential with the Liquid Extension JSON
* and submit it to the service for verification
*/
val credential = PublicKeyCredential.deserializeFromBytes(bytes)
}
}
}
// Register/Attestation Intent Launcher
val assertionIntentLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
::handleAuthenticatorAssertionResult
)
// Launch the FIDO2 Intent
val pendingIntent = fido2Client.getRegisterPendingIntent(publicKeyCredentialRequestOptions).await()
assertionIntentLauncher.launch(
IntentSenderRequest.Builder(pendingIntent).build()
)

🔐 Liquid Extension

The liquid extension is optional for authentication requests.

This is useful when you already have a passkey and want to peer with a device that is not signed in.

val liquidExtJSON = JSONObject()
// Optionally authenticate a remote peer
liquidExtJSON.put("requestId", requestId)

🚚 Response

MainActivity.kt
val response = assertionApi.postAssertionResponse(
origin, // Origin Server
userAgent, // Required for checking the authenticator fingerprint
credential, // PublicKeyCredential
liquidExtJSON // Liquid Extension JSON
)