Klass Online · Biometric Authentication Android
Authentication — Android
Implementation
Autofill Password & Biometric Integration
Klass Online Mobile App · May 2026 · Platform: Android | Stack: Flutter
This document covers Android only.
1. Packages
Package Version Purpose
flutter_secure_storage v10.2.0 Stores credentials and tokens using Android
Keystore-backed EncryptedSharedPreferences
(AES-256). No plain-text storage.
local_auth v3.0.1 Flutter wrapper over Android's BiometricPrompt API.
Prompts fingerprint, face unlock, or device PIN/pattern.
Requires USE_BIOMETRIC permission in
[Link].
No third-party auth SDKs or custom native Kotlin code are required. These two packages
are sufficient for full Android compliance.
2. Native Credential Storage — Android Keystore
Android Keystore-backed encrypted storage via flutter_secure_storage.
No plain-text or local-database credential caching will remain in the app after this migration.
Data Storage Before Storage After Access Control
Access Token GetStorage EncryptedSharedPreferences When device is
(Keystore) unlocked
Refresh Token GetStorage EncryptedSharedPreferences After first unlock
(Keystore)
Saved Email / Not stored EncryptedSharedPreferences Biometric-gated read
Password (Keystore)
3. Native AutoFill — Digital Asset Links
Confidential — Internal Use OnlyPage
Klass Online · Biometric Authentication Android
Android Password AutoFill requires a Digital Asset Links file linking the app to the backend domain.
This enables the Android autofill framework (and Google Password Manager) to suggest saved
credentials on the login screen.
Step Where Detail
1. Host [Link] Backend server JSON at /.well-known/[Link] with app
file package name and signing certificate fingerprint
2. Mark TextFields with Flutter login screen [Link], [Link]
autofill hints
3. Wrap fields in Flutter login screen Triggers Save Password prompt on successful
AutofillGroup submit
Already in place: Both login fields are wrapped in AutofillGroup and annotated with
[Link], [Link], and [Link].
Save Password Prompt: Calling [Link](shouldSave: true) on a successful
login response triggers the native Android 'Save Password' bottom sheet automatically. Calling it
with shouldSave: false on every failure path ensures bad credentials are never offered for saving.
Both are already implemented.
4. Biometric Authentication Logic
Important: Biometric is a session-unlock gate only — it does NOT replace backend
authentication. The backend JWT flow remains entirely unchanged.
4.1 User Flow
Step Action
1. First login User enters email + password → backend authenticates → JWT tokens saved in
Keystore
2. App Session locked in-app (not logged out); tokens remain in Keystore
backgrounds
3. App returns to Android BiometricPrompt displayed (fingerprint / face / PIN)
foreground
4. Biometric Refresh token retrieved from Keystore → silent call to /auth/jwt/refresh → session
success resumed
5. Biometric User redirected to login screen; stored tokens untouched
failure / cancel
Confidential — Internal Use OnlyPage
Klass Online · Biometric Authentication Android
5. Credential Invalidation
Stored credentials and tokens will be cleared under the following events:
Trigger Event Action Keystore Behaviour
Logout Delete all encrypted entries Manual delete via
flutter_secure_storage
Password change Invalidate stored credentials Delete + prompt re-save on next login
Account removal Full encrypted storage wipe for deleteAll()
app
Biometric enrollment Invalidate Keystore key Requires
change setInvalidatedByBiometricEnrollment(tr
ue) — see Section 10.1
App uninstall Automatic full wipe Android OS handles this automatically
— no code required
6. UI / Error Handling
All biometric prompts use the native Android BiometricPrompt bottom sheet via the local_auth
package. No custom biometric UI is built. Custom UI is only used for post-error in-app navigation
(e.g., routing back to the login screen).
Error State Trigger Handling
Biometric lockout Too many failed attempts Fall back to device PIN/pattern or redirect
to login screen
No biometric enrolled Device has no fingerprint / face Skip biometric gate; go directly to full
set up login
User cancellation User dismisses the prompt Show login screen with option to retry
biometric
Device security disabled No PIN / lock set on device Disable biometric feature; inform user to
set a device lock
Confidential — Internal Use OnlyPage
Klass Online · Biometric Authentication Android
7. No Conflicting Flows
The app will use exactly one autofill mechanism — Flutter's native AutofillGroup combined
with Digital Asset Links. No custom Save Password dialog will be built. This guarantees a
single native Android prompt with no duplicates.
8. [Link] Changes Required
Change Location Purpose
USE_BIOMETRIC permission [Link] Required to call BiometricPrompt —
already present
android:usesCleartextTraffic="f <application> tag Currently set to true — should be locked
alse" down before production release
9. QA — Physical Device Testing
Biometric and Keystore behaviour cannot be reliably tested on emulators.
All QA for this feature will be performed on real Android hardware.
Test Case Device
Fingerprint prompt and unlock Google Pixel 9a
Face unlock prompt and unlock OnePlus 9
Keystore persistence across app restarts Both devices
Biometric enrollment invalidation (add new fingerprint) Both devices
AutoFill suggestion on login screen Both devices with Google
Password Manager active
Save Password sheet after login / registration Both devices — Android 11+
Google Password Manager autofill suggestion Google Pixel 9a (stock Android)
OxygenOS autofill / password manager behaviour OnePlus 9
Lockout handling after 5 failed biometric attempts Both devices
Fallback to PIN after biometric failure Both devices
Confidential — Internal Use OnlyPage