{"record":{"id":"bcbf44c4c0ab4186","repo":"apereo/cas","slug":"missing-web-authn-token-from-the-request","errorCode":null,"errorMessage":"Missing web authn token from the request","messagePattern":"Missing web authn token from the request","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-webauthn-core-webflow/src/main/java/org/apereo/cas/webauthn/web/flow/WebAuthnValidateSessionCredentialTokenAction.java","lineNumber":45,"sourceCode":" * @since 6.3.0\n */\n@RequiredArgsConstructor\n@Slf4j\npublic class WebAuthnValidateSessionCredentialTokenAction extends AbstractMultifactorAuthenticationAction<WebAuthnMultifactorAuthenticationProvider> {\n    protected final RegistrationStorage webAuthnCredentialRepository;\n\n    protected final SessionManager sessionManager;\n\n    protected final PrincipalFactory principalFactory;\n\n    protected final TenantExtractor tenantExtractor;\n    \n    @Override\n    protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {\n        val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);\n        val token = request.getParameter(\"token\");\n        if (StringUtils.isBlank(token)) {\n            LOGGER.warn(\"Missing web authn token from the request\");\n            return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_AUTHENTICATION_FAILURE);\n        }\n\n        LOGGER.debug(\"Received web authn token [{}]\", token);\n        val credential = new WebAuthnCredential(token);\n        WebUtils.putCredential(requestContext, credential);\n\n        val session = sessionManager.getSession(request, WebAuthnCredential.from(credential));\n        if (session.isEmpty()) {\n            LOGGER.warn(\"Unable to locate existing session from the current token [{}]\", token);\n            return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_AUTHENTICATION_FAILURE);\n        }\n        val result = webAuthnCredentialRepository.getUsernameForUserHandle(session.get());\n        if (result.isEmpty()) {\n            LOGGER.warn(\"Unable to locate user based on the given user handle\");\n            return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_AUTHENTICATION_FAILURE);\n        }\n        val username = result.get();","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-webauthn-core-webflow/src/main/java/org/apereo/cas/webauthn/web/flow/WebAuthnValidateSessionCredentialTokenAction.java#L27-L63","documentation":"The WebAuthn session-validation webflow action expects a 'token' HTTP parameter carrying the WebAuthn credential token, but it is blank or absent, so doExecuteInternal logs a warning and transitions to authentication failure. No credential can be built without it.","triggerScenarios":"WebAuthnValidateSessionCredentialTokenAction.doExecuteInternal reads request.getParameter(\"token\") from the servlet request (via the webflow external context) and finds StringUtils.isBlank(token) — the validation link/POST omitting or emptying the token parameter.","commonSituations":"A custom login page or template dropped the hidden token field; an email/link-based WebAuthn validation flow where the user clicks a URL whose token query param got stripped by a proxy or URL sanitizer; user navigating directly to the validation URL without the token.","solutions":["Ensure the page/link that triggers WebAuthn session validation includes the token parameter (e.g. hidden form field or query string) exactly as generated by CAS.","Check reverse proxies/URL rewriters aren't stripping or truncating the token query parameter.","Restart the flow from the login page so CAS regenerates a fresh token rather than replaying an old URL."],"exampleFix":"// before (form missing token)\n<form method=\"post\" action=\".../webauthn/validate\">...</form>\n\n// after\n<form method=\"post\" action=\".../webauthn/validate\">\n  <input type=\"hidden\" name=\"token\" th:value=\"${token}\"/>\n  ...\n</form>","handlingStrategy":"validation","validationCode":"// before invoking the WebAuthn validation action/endpoint\nconst token = params.get('token');\nif (!token || token.trim() === '') {\n  throw new Error('token parameter is required for WebAuthn session validation');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always render the generated token in the hidden form field or link that triggers validation.","Check proxies/URL sanitizers don't strip the token query parameter.","Have users restart the flow from login when the validation link has no token."],"tags":["webauthn","mfa","webflow","missing-parameter"],"backgroundTag":"missing-required-argument","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}