Multi-Factor Authentication
Multi-factor authentication (MFA) requires users to prove their identity with more than one factor: typically something they know (a password) combined with something they have (a device or security key) or something they are (a biometric). IdentityServer handles the protocol layer (OpenID Connect, OAuth 2.0, SAML) and delegates the actual authentication experience, including MFA, to the hosting application’s login UI.
MFA with Duende User Management
Section titled “MFA with Duende User Management”Duende User Management provides production-ready MFA building blocks that integrate directly with IdentityServer. The library handles the cryptographic operations, credential storage, verification logic, and rate limiting. You provide the UI.
Supported second factors:
| Method | Description | Use Case |
|---|---|---|
| TOTP | Time-based codes from authenticator apps (Microsoft Authenticator, Google Authenticator, etc.) | Most common MFA for enterprise apps |
| Passkeys | WebAuthn/FIDO2 phishing-resistant authentication via biometrics or hardware keys | Highest security; can also serve as primary auth |
| OTP | One-time codes delivered via email or SMS | Step-up authentication or passwordless primary |
| Recovery Codes | Single-use backup codes | Fallback when the primary 2FA method is unavailable |
A typical MFA flow with User Management:
- User authenticates with a primary factor (password, OTP, or external provider)
- Application checks whether the user has a second factor enrolled
- User completes the second-factor challenge (TOTP code, passkey ceremony, etc.)
- Application establishes the IdentityServer session with an
amrclaim reflecting MFA being used
public class LoginModel( IUserAuthenticatorsSelfService authenticatorsSelfService) : PageModel{ public async Task<IActionResult> AfterPrimaryAuthSucces(UserSubjectId userId, CancellationToken ct) { var authenticators = await authenticatorsSelfService.TryGetAsync(userId, ct);
if (authenticators?.TotpDeviceNames.Count > 0) { // Redirect to TOTP verification page return RedirectToPage("/LoginWith2FA"); }
if (authenticators?.Passkeys.Count > 0) { // Redirect to passkey verification page return RedirectToPage("/LoginWithPasskey"); }
return RedirectToPage("/LoginWithRecoveryCode"); }}For detailed implementation guides, see:
- Authentication Flows Overview: choosing the right combination of methods
- TOTP Authentication: setup, verification, and recovery codes
- Passkey Authentication: WebAuthn ceremonies and second-factor configuration
- OTP Authentication: passwordless codes via email or SMS
- Recovery Codes: backup access when the primary second factor is unavailable
MFA with ASP.NET Core Identity
Section titled “MFA with ASP.NET Core Identity”If you are using ASP.NET Core Identity as your user store, it provides its own MFA support including TOTP with authenticator apps. Microsoft’s general MFA guidelines cover configuration options for ASP.NET Core.
MFA and External Authentication
Section titled “MFA and External Authentication”When using IdentityServer as a federation gateway, interactive users authenticate at the upstream identity provider. The upstream provider handles the entire authentication process, including any MFA it requires. No special configuration is needed in IdentityServer for this scenario.
Requesting MFA from Clients
Section titled “Requesting MFA from Clients”Clients can signal that MFA is required using the acr_values parameter in the authorization request.
Your login UI can read this from the authorization context and enforce a second-factor
challenge accordingly:
var context = await interaction.GetAuthorizationContextAsync(returnUrl, HttpContext.RequestAborted);
if (context?.AcrValues.Contains("mfa") == true){ // Enforce second-factor authentication regardless of user preference}