Skip to content

Commit 40408ca

Browse files
committed
fix: enable Spring Security factor merging so MFA can actually complete
Without @EnableMultiFactorAuthentication, a successful WebAuthn assertion REPLACED the session authentication instead of adding to it: the user went from satisfiedFactors=[PASSWORD] to [WEBAUTHN], never both, bouncing between the two factor challenges forever. Spring Security 7 only merges authorities across logins when mfaEnabled is set on the authentication filters, which the annotation's BeanPostProcessor does. The framework's user.mfa support configures the authorization half but not this filter half, so the demo wires it explicitly (conditional on user.mfa.enabled).
1 parent 8f11f7a commit 40408ca

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.digitalsanctuary.spring.demo.config;
2+
3+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication;
6+
7+
/**
8+
* Enables Spring Security 7's MFA filter support when {@code user.mfa.enabled=true}.
9+
*
10+
* <p>
11+
* {@code @EnableMultiFactorAuthentication} registers a {@code BeanPostProcessor} that sets {@code mfaEnabled} on the
12+
* authentication filters. With it, a second login in the same session (e.g. a WebAuthn assertion after a password
13+
* login) <em>merges</em> the new authentication's authorities with the current ones, accumulating
14+
* {@code FactorGrantedAuthority}s. Without it, the passkey verification <em>replaces</em> the session authentication,
15+
* dropping the PASSWORD factor — the user can then never satisfy both factors and bounces between the two challenge
16+
* pages forever.
17+
* </p>
18+
*
19+
* <p>
20+
* The {@code authorities} attribute is left empty on purpose: the Spring User Framework already configures the
21+
* required-factor authorization rules from the {@code user.mfa.factors} property.
22+
* </p>
23+
*/
24+
@Configuration
25+
@ConditionalOnProperty(name = "user.mfa.enabled", havingValue = "true", matchIfMissing = false)
26+
@EnableMultiFactorAuthentication(authorities = {})
27+
public class MfaSecurityConfig {
28+
}

0 commit comments

Comments
 (0)