{"record":{"id":"6fa42c192838f340","repo":"spring-projects/spring-security","slug":"when-when-includes-multifactorcondition-webauth","errorCode":null,"errorMessage":"When when() includes {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities() must include {FactorGrantedAuthority.WEBAUTHN_AUTHORITY}","messagePattern":"When when\\(\\) includes (.+?), authorities\\(\\) must include (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"config/src/main/java/org/springframework/security/config/annotation/authorization/MultiFactorAuthenticationSelector.java","lineNumber":54,"sourceCode":" * {@link org.springframework.security.core.authority.FactorGrantedAuthority#WEBAUTHN_AUTHORITY}\n * and throws an {@link IllegalArgumentException} if not.\n *\n * @author Rob Winch\n * @since 7.0\n * @see EnableMultiFactorAuthentication\n */\nclass MultiFactorAuthenticationSelector implements ImportSelector {\n\n\t@Override\n\tpublic String[] selectImports(AnnotationMetadata metadata) {\n\t\tMap<String, Object> multiFactorAuthenticationAttrs = metadata\n\t\t\t.getAnnotationAttributes(EnableMultiFactorAuthentication.class.getName());\n\t\tString[] authorities = (String[]) multiFactorAuthenticationAttrs.getOrDefault(\"authorities\", new String[0]);\n\t\tMultiFactorCondition[] when = (MultiFactorCondition[]) multiFactorAuthenticationAttrs.getOrDefault(\"when\",\n\t\t\t\tnew MultiFactorCondition[0]);\n\t\tboolean hasWebAuthn = Arrays.asList(when).contains(MultiFactorCondition.WEBAUTHN_REGISTERED);\n\t\tif (hasWebAuthn && !Arrays.asList(authorities).contains(FactorGrantedAuthority.WEBAUTHN_AUTHORITY)) {\n\t\t\tthrow new IllegalArgumentException(\"When when() includes \" + MultiFactorCondition.WEBAUTHN_REGISTERED\n\t\t\t\t\t+ \", authorities() must include \" + FactorGrantedAuthority.WEBAUTHN_AUTHORITY);\n\t\t}\n\t\tList<String> imports = new ArrayList<>(3);\n\t\tif (authorities.length > 0) {\n\t\t\timports.add(AuthorizationManagerFactoryConfiguration.class.getName());\n\t\t\tif (hasWebAuthn) {\n\t\t\t\timports.add(WhenWebAuthnRegisteredMfaConfiguration.class.getName());\n\t\t\t}\n\t\t}\n\t\timports.add(EnableMfaFiltersConfiguration.class.getName());\n\t\treturn imports.toArray(new String[imports.size()]);\n\t}\n\n}\n","sourceCodeStart":36,"sourceCodeEnd":69,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/config/src/main/java/org/springframework/security/config/annotation/authorization/MultiFactorAuthenticationSelector.java#L36-L69","documentation":"MultiFactorAuthenticationSelector.selectImports validates @EnableMultiFactorAuthentication attributes: if when() includes MultiFactorCondition.WEBAUTHN_REGISTERED, the authorities() list must contain FactorGrantedAuthority.WEBAUTHN_AUTHORITY, otherwise it throws IllegalArgumentException. This ensures the WebAuthn registration condition has the matching factor authority to evaluate against.","triggerScenarios":"Annotating @EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities = {...}) where the authorities array omits FactorGrantedAuthority.WEBAUTHN_AUTHORITY (note: the check compares the given strings against the constant, so the constant's string value must be present exactly).","commonSituations":"Typo or custom string in authorities() instead of the exact WEBAUTHN_AUTHORITY value; enabling the WebAuthn condition during a migration from password-only multi-factor config; copy-pasted annotation attributes from a non-WebAuthn example.","solutions":["Include FactorGrantedAuthority.WEBAUTHN_AUTHORITY in the authorities() attribute of @EnableMultiFactorAuthentication.","Use the constant directly in code: FactorGrantedAuthority.WEBAUTHN_AUTHORITY, rather than a hand-typed string.","Remove MultiFactorCondition.WEBAUTHN_REGISTERED from when() if WebAuthn factor enforcement is not intended.","Align the annotation with the documented combination, e.g. @EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities = {FactorGrantedAuthority.WEBAUTHN_AUTHORITY})."],"exampleFix":"// before\n@EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED}, authorities = {\"OTP\"})\n// after\n@EnableMultiFactorAuthentication(when = {MultiFactorCondition.WEBAUTHN_REGISTERED},\n    authorities = {FactorGrantedAuthority.WEBAUTHN_AUTHORITY})","handlingStrategy":"validation","validationCode":"MultiFactorCondition[] when = ...; String[] authorities = ...;\nif (Arrays.asList(when).contains(MultiFactorCondition.WEBAUTHN_REGISTERED)\n        && !Arrays.asList(authorities).contains(FactorGrantedAuthority.WEBAUTHN_AUTHORITY)) {\n    throw new IllegalArgumentException(\"authorities() must include FactorGrantedAuthority.WEBAUTHN_AUTHORITY\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    context = applicationContext; // annotation processed at startup\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"WEBAUTHN_AUTHORITY\")) {\n        throw new ConfigurationException(\"Fix @EnableMultiFactorAuthentication attributes\", e);\n    }\n    throw e;\n}","preventionTips":["Use the FactorGrantedAuthority.WEBAUTHN_AUTHORITY constant, not a hand-written string","Keep when() and authorities() attributes consistent","Review annotation attributes when upgrading Spring Security versions","Add an integration test that boots the annotation-processed context"],"tags":["multifactor","webauthn","configuration","annotation"],"backgroundTag":"conflicting-config-options","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}