Still unlocking your apps with a four‑digit PIN? In 2025 that’s like locking Fort Knox with a paperclip. Let’s upgrade your security—and your CV—by wiring fingerprint and facial recognition into your .NET MAUI applications in less than a coffee break.
Why Bother With Biometrics?
User research consistently shows that people will choose convenience over security—unless they can enjoy both. Biometrics provide friction‑free sign‑in backed by hardware‑level protection, reducing password‑reset tickets and improving conversion rates. In short: you win, the user wins, the hacker loses.
Real‑world wins
- Kill the password reset loop – biometric fallback means fewer password emails.
- Regulatory brownie points – PSD2, HIPAA and friends love multi‑factor flows.
- Better UX metrics – our average time‑to‑first‑action dropped from 8 s to <3 s on iOS when we enabled Face ID.
Platform Support Cheat‑Sheet
Platform | Fingerprint | Face/IR | Library/Notes |
---|---|---|---|
Android 5.0+ | ✅BiometricPrompt | ✅(face/iris on devices that expose it) | Oscore.Maui.Biometric |
iOS 12.2+ | ✅Touch ID | ✅Face ID | Oscore.Maui.Biometric ; set NSFaceIDUsageDescription |
Windows 10 1809+ | ✅Windows Hello | ✅Windows Hello | WinRT under the hood via Oscore.Maui.Biometric |
macOS 15+ | ✅Touch ID | 🚫Face | Use fingerprint only |
Heads‑up: If you target older hardware, always implement a secure PIN fallback or skip biometrics when
availability.CanAuthenticate
returnsfalse
.
Setting Up the Project
- Install the NuGet package
dotnet add package Oscore.Maui.Biometric
- Wire up the service in
MauiProgram.cs
using Oscore.Maui.Biometric;
builder
.UseMauiApp<App>()
.UseBiometricAuthentication() // registers IBiometricAuthentication
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
- Add platform permissions
Android AndroidManifest.xml
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" android:maxSdkVersion="27" />
iOS Info.plist
<key>NSFaceIDUsageDescription</key>
<string>This app uses Face ID to keep your data safe and your life easy.</string>
Fingerprint Flow in Five Lines
Here’s the minimal page‑level code that greeted me during a code review—and passed with flying colours:
var biometric = BiometricAuthentication.Current;
var availability = await biometric.GetAvailabilityAsync();
if (!availability.CanAuthenticate)
await DisplayAlert("Sorry", availability.GetErrorMessage(), "OK");
var result = await biometric.AuthenticateAsync(
new BiometricAuthenticationRequest
{
Title = "Sign in",
Description = "Scan your fingerprint"
},
CancellationToken.None);
if (result.Authenticated)
await Shell.Current.GoToAsync("//Home");
Tip: cache the success in
SecureStorage
. Most apps skip the second scan until the next cold start.
Face ID & Windows Hello
Face authentication is the same API—no extra code! The OS decides whether to surface a face, fingerprint or PIN prompt.
// Works for Touch ID, Face ID, and Hello
var result = await biometric.AuthenticateAsync(
new BiometricAuthenticationRequest
{
Title = "Verify it’s really you",
NegativeText = "Use password instead"
});
Custom Face Matching (advanced)
Need your own face database (e.g., factory attendance kiosks)? Plug in the Azure Face API or OpenCV:
- Capture a selfie via
MediaPicker
. - Send to
FaceClient.DetectWithStreamAsync
. - Store
faceId
in your backend and compare withFaceClient.VerifyAsync
.
Keep local copies encrypted; GDPR fines hurt more than broken builds.
UX Best Practices
- Show the OS dialog instantly after the button tap—no spinners.
- Explain why: users get suspicious if a random biometric sheet pops up.
- Fallback gracefully to password/PIN after three failed attempts.
- Dark mode: Windows Hello dropped infrared‑only support in June 2025, so ensure a visible‑light camera is present.
Security Pitfalls I’ve Stepped Into
- Assuming authentication ≠ authorization. Re‑check server‑side tokens.
- Caching indefinitely. Store the timestamp and re‑prompt after 12 h.
- Forgetting screenshot protections: enable
FLAG_SECURE
on Android (Window.SetFlags
).
Testing Across Platforms
- Android Studio Emulator →
Extended controls › Fingerprint › Touch sensor
to simulate scans. - iOS Simulator →
Device › Face ID › Enrolled
. - Windows → spoof Windows Hello with
WindowsHelloSimulator.exe
(comes with Windows SDK 10.1+).
Automate with UITest by triggering AuthenticateAsync()
behind an #if DEBUG
flag that bypasses the call and returns Success
.
FAQ: Biometric Gotchas in MAUI
Not reliably. iOS decides. Ask only for “biometric” and respect the user’s choice.
Nope, because the underlying platforms (Android/iOS/Windows/macOS) expose secure enclaves; GTK builds run on distros without a uniform secure enclave API.
Abstract IBiometricAuthentication
behind your own interface and inject a mock that returns canned results.
Passkeys wrap biometrics for the web. You can host WebView2 and delegate to a FIDO2 endpoint, but that’s a separate article.
Conclusion: Ship It Securely—And Let Your Users Smile
You now have a battle‑tested recipe to add fingerprint and face authentication to any .NET MAUI app with just a NuGet, five lines of code, and a sprinkle of permissions. Users log in faster, your audit logs look cleaner, and your boss thinks you’re a magician. Ready to push to production? Do it—and drop a comment telling me how much time you saved.