Passwords have protected applications for decades, but they continue to be one of the weakest links in application security. Weak passwords, phishing attacks, credential stuffing, and password reuse remain common causes of security breaches. Passkeys offer a modern alternative by enabling passwordless authentication based on public-key cryptography, providing both stronger security and a better user experience.
For organizations with existing ASP.NET Core Identity applications, however, the challenge isn't enabling passkeys—it's introducing them without disrupting existing users or authentication flows. A successful migration should allow passwords and passkeys to coexist until users gradually adopt the new authentication method.
In this article, we'll build a migration strategy for adding passkey support to an ASP.NET Core Identity application while maintaining backward compatibility for existing users.
Understanding Passkeys
What Are Passkeys?
Passkeys are based on the FIDO2/WebAuthn standard. Instead of storing passwords, users authenticate using a cryptographic key pair.
The authentication process works as follows:
A public key is stored by the application.
A private key remains securely stored on the user's device.
During sign-in, the device proves possession of the private key.
No password is transmitted or stored.
This significantly reduces the risk of phishing and credential theft.
Why Add Passkeys Instead of Replacing Passwords?
Support Existing Users
Most enterprise applications already have thousands—or even millions—of registered users.
Removing password authentication overnight would:
Break existing login workflows
Increase support requests
Create unnecessary migration risks
A gradual adoption strategy allows users to register passkeys while continuing to use passwords until they're ready to switch.
Existing Authentication Architecture
A typical ASP.NET Core Identity application looks like this:
User
│
▼
Login Page
│
▼
ASP.NET Core Identity
│
▼
Identity Database
Password verification occurs through the Identity framework before granting access to protected resources.
Adding Passkey Support
Instead of replacing Identity, extend it.
Updated architecture:
User
│
┌───────────┴───────────┐
▼ ▼
Password Login Passkey Login
│ │
└───────────┬───────────┘
▼
ASP.NET Core Identity
│
▼
Identity Database
Both authentication methods share the same user account, allowing gradual migration without affecting existing users.
Configuring ASP.NET Core Identity
Identity registration remains largely unchanged.
builder.Services
.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Why Keep Identity?
ASP.NET Core Identity already provides:
Adding passkeys extends these capabilities rather than replacing them, allowing existing authentication features to continue working.
Registering a Passkey
After users authenticate using their existing password, provide an option to register a passkey.
public async Task RegisterPasskeyAsync(
ApplicationUser user)
{
// Generate WebAuthn registration challenge
// Send challenge to browser
// Store public key after verification
}
Why Register After Login?
Requiring existing authentication before passkey registration ensures that only legitimate account owners can associate new credentials with their accounts.
This also provides a seamless onboarding experience because users don't need to create a separate account.
Authenticating with a Passkey
Once registration is complete, users can authenticate without entering a password.
public async Task AuthenticatePasskeyAsync()
{
// Generate authentication challenge
// Verify signed response
// Sign in user
}
Why Separate Registration and Authentication?
Registration establishes trust by storing the public key.
Authentication verifies possession of the corresponding private key, allowing secure passwordless sign-in without transmitting secrets over the network.
End-to-End Migration Workflow
Consider an existing employee portal.
The migration process could follow these steps:
Employees continue signing in with passwords.
After successful authentication, the application offers passkey registration.
The employee creates a passkey using Windows Hello, Face ID, Touch ID, or a hardware security key.
The public key is stored alongside the existing Identity account.
Future logins allow users to choose either a password or a passkey.
Once adoption reaches organizational targets, password authentication can optionally be phased out.
This approach minimizes disruption while improving account security over time.
Managing Multiple Authentication Methods
Many organizations require more than one sign-in option.
An authentication page might offer:
ASP.NET Core Identity supports combining these methods without maintaining separate user accounts.
This flexibility allows organizations to introduce passkeys while continuing to support existing enterprise authentication requirements.
Comparison of Authentication Methods
| Authentication Method | User Experience | Phishing Resistance | Migration Complexity |
|---|
| Password | Familiar | Low | None |
| Password + MFA | Better security | Medium | Low |
| Passkey | Excellent | High | Medium |
| Passkey Only | Excellent | High | High |
For most organizations, supporting both passwords and passkeys during migration provides the best balance between usability and security.
Best Practices
Introduce passkeys as an additional sign-in option.
Require existing authentication before passkey registration.
Continue supporting password recovery during migration.
Educate users about passwordless authentication.
Use ASP.NET Core Identity as the central authentication system.
Log authentication events for auditing.
Encourage users to register multiple passkeys across trusted devices.
Test authentication flows across supported browsers and platforms.
Common Mistakes
One common mistake is forcing all users to switch to passkeys immediately. This can disrupt user access, especially in enterprise environments with diverse devices and authentication requirements.
Another issue is treating passkeys as a replacement for Identity. Identity should remain responsible for user management, authorization, claims, and account lifecycle management.
Developers also sometimes overlook recovery scenarios. Users who lose access to a registered device still need a secure method to regain access to their accounts.
Testing and Validation
Before deploying passkey authentication, validate the complete authentication lifecycle.
Recommended testing includes:
User registration
Passkey registration
Password login
Passkey login
Account recovery
Multi-device registration
Cross-browser compatibility
Cross-platform testing
Regression testing of existing Identity features
Testing should confirm that introducing passkeys does not affect users who continue to authenticate with passwords.
Performance Considerations
Passkey authentication generally introduces minimal server overhead because cryptographic verification is lightweight compared to many application operations.
To maintain good performance:
Cache user profile data where appropriate.
Keep authentication endpoints lightweight.
Monitor authentication latency.
Minimize unnecessary database queries.
Use asynchronous APIs throughout the authentication pipeline.
Load-test authentication endpoints before deployment.
Performance improvements should always be measured under production-like workloads.
Security Considerations
Passkeys significantly improve authentication security, but secure implementation remains essential.
Follow these recommendations:
Always use HTTPS.
Validate every authentication challenge.
Store only public keys on the server.
Protect authentication endpoints against replay attacks.
Enable rate limiting on login endpoints.
Continue using role-based authorization after authentication.
Audit registration and login events.
Keep Identity and authentication libraries up to date.
Security should focus on the complete authentication process, not just the sign-in mechanism.
Troubleshooting
Passkey Registration Fails
Verify that the browser and device support WebAuthn and that HTTPS is enabled. Most browsers require secure origins for passkey operations.
Users Cannot Authenticate
Confirm that the registered public key matches the user's account and that authentication challenges are being generated and validated correctly.
Existing Password Login Stops Working
Review Identity configuration to ensure passkey support has been added alongside, rather than replacing, the existing authentication pipeline.
Cross-Device Issues
Ensure users register passkeys on each trusted device they intend to use, or leverage platform synchronization features where available.
Conclusion
Passkeys represent a significant step forward in modern authentication by reducing reliance on passwords and improving resistance to phishing attacks. For ASP.NET Core Identity applications, the key to successful adoption is introducing passkeys gradually rather than replacing existing authentication overnight. By allowing passwords and passkeys to coexist, organizations can modernize security without disrupting users, simplify future authentication workflows, and build applications that are better prepared for passwordless authentication.