|
Warning
|
Experimental Module: This module is still experimental. The public API may change between library releases without following semantic versioning conventions used by other yubikit-android modules. Use with caution in production environments. |
The FIDO Android UI module provides a high-level FIDO2/WebAuthn client with built-in UI components for Android applications. This module simplifies the integration of hardware security key authentication by handling the complete user interaction flow, including NFC/USB communication, PIN entry, and user prompts.
To add the FIDO Android UI module as a dependency to your project, add the following to your gradle configuration:
dependencies {
implementation 'com.yubico.yubikit:fido-android-ui:(insert version here)'
}-
Complete FIDO2/WebAuthn client implementation with built-in UI for user interactions
-
WebView integration for seamless passkey support in web applications
-
Native app support for direct FIDO operations without WebView
-
Automatic device discovery over NFC and USB
-
PIN management UI with configurable workflow (PIN-first or touch-first)
-
Extension support including CredBlob, CredProps, CredProtect, HmacSecret, LargeBlob, and MinPinLength
-
Customizable theming to match your app’s design
-
Jetpack Compose UI with Material Design components
The FidoClient class is the primary API for performing FIDO operations. It handles credential creation (registration) and assertion (authentication) with automatic UI presentation.
Create an instance from a Fragment or Activity during initialization:
class MyFragment : Fragment() {
private lateinit var fidoClient: FidoClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Create client with default extensions
fidoClient = FidoClient(this)
// Or with custom extensions
fidoClient = FidoClient(
this,
listOf(
CredPropsExtension(),
HmacSecretExtension(),
LargeBlobExtension()
)
)
}
}Use makeCredential() for user registration:
lifecycleScope.launch {
val origin = Origin("https://example.com")
val requestJson = """
{
"challenge": "...",
"rp": {"id": "example.com", "name": "Example"},
"user": {
"id": "...",
"name": "user@example.com",
"displayName": "User Name"
},
"pubKeyCredParams": [{"type": "public-key", "alg": -7}]
}
"""
fidoClient.makeCredential(origin, requestJson, null)
.onSuccess { credentialJson ->
// credentialJson contains the PublicKeyCredential response
// Send to your server for validation
logger.info("Registration successful: $credentialJson")
}
.onFailure { error ->
logger.error("Registration failed", error)
}
}Use getAssertion() for user authentication:
lifecycleScope.launch {
val origin = Origin("https://example.com")
val requestJson = """
{
"challenge": "...",
"rpId": "example.com",
"allowCredentials": [
{"type": "public-key", "id": "..."}
]
}
"""
fidoClient.getAssertion(origin, requestJson, null)
.onSuccess { assertionJson ->
// assertionJson contains the PublicKeyCredential response
// Send to your server for validation
logger.info("Authentication successful: $assertionJson")
}
.onFailure { error ->
logger.error("Authentication failed", error)
}
}For web applications, enable FIDO WebAuthn support in a WebView to allow web pages to use navigator.credentials APIs:
class FidoFragment : Fragment() {
private lateinit var fidoClient: FidoClient
private lateinit var webView: WebView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
fidoClient = FidoClient(this)
val view = inflater.inflate(R.layout.fragment_fido, container, false)
webView = view.findViewById(R.id.webView)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Enable DOM storage for web apps
webView.settings.domStorageEnabled = true
// Enable FIDO WebAuthn support
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
webView.enableFidoWebauthn(lifecycleScope, fidoClient)
} else {
logger.warn("Web Message Listener not supported")
}
// Load a WebAuthn-enabled site
webView.loadUrl("https://passkey.org")
}
}The WebView integration automatically:
-
Intercepts
navigator.credentials.create()andnavigator.credentials.get()calls -
Injects necessary JavaScript polyfills
-
Routes requests through the FidoClient
-
Handles HTTPS-only enforcement
-
Returns properly formatted responses to the web page
Use FidoConfigManager to customize the FIDO UI behavior globally:
// Prioritize PIN entry before device interaction
FidoConfigManager.setIsPinPrioritized(true)
// Set custom extensions globally
FidoConfigManager.setExtensions(
listOf(
LargeBlobExtension(),
HmacSecretExtension()
)
)
// Apply custom theme
FidoConfigManager.setTheme { content ->
MyAppTheme {
content()
}
}
// Or update configuration atomically
FidoConfigManager.update { config ->
config.copy(
isPinPrioritized = true,
fidoExtensions = listOf(...)
)
}
// Observe configuration changes
lifecycleScope.launch {
FidoConfigManager.configuration.collect { config ->
logger.info("Config updated: $config")
}
}Complete working examples can be found in the AndroidDemo application:
-
WebView integration: FidoFragment.kt
-
Demonstrates WebView setup with multiple test sites
-
Shows how to clear cookies and reload pages
-
Includes extension configuration
-
-
Native app integration: FidoAppLocalFragment.kt
-
Shows direct makeCredential/getAssertion usage
-
Demonstrates request building
-
Includes error handling patterns
-
-
HTTPS Only: All origins must use HTTPS. HTTP origins will be rejected.
-
Origin Validation: The module validates that the request origin matches expected patterns.
-
PIN Protection: PINs are handled securely and never logged or exposed in plain text.
-
Single Request: Only one FIDO operation can be in progress at a time.
-
iframe Restrictions: WebView integration does not support requests from iframes.
All FidoClient operations are suspending functions that must be called from a coroutine context. The module handles all necessary thread coordination internally, including:
-
UI interactions on the main thread
-
NFC/USB communication on background threads
-
Cryptographic operations
-
JSON serialization/deserialization
The module supports the following FIDO2 extensions:
-
credBlob: Store small amounts of data with credentials
-
credProps: Get credential properties (rk, authenticatorDisplayName)
-
credProtect: Configure user verification requirements
-
hmacSecret (PRF): Generate pseudo-random functions
-
largeBlob: Store larger data blobs
-
minPinLength: Query minimum PIN length requirements
Extensions can be configured per-client or globally via FidoConfigManager.