{"record":{"id":"b29550fb8eb91fc4","repo":"spring-projects/spring-security","slug":"oauth-2-0-parameter-parametername-b29550","errorCode":null,"errorMessage":"OAuth 2.0 Parameter: ${parameterName}","messagePattern":"OAuth 2\\.0 Parameter: (.+?)","errorType":"error_code","errorClass":"OAuth2AuthorizationCodeRequestAuthenticationException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationConsentAuthenticationConverter.java","lineNumber":126,"sourceCode":"\t\t\t}\n\t\t});\n\n\t\treturn new OAuth2AuthorizationConsentAuthenticationToken(authorizationUri, clientId, principal, state, scopes,\n\t\t\t\tadditionalParameters);\n\t}\n\n\tstatic RequestMatcher createDefaultRequestMatcher() {\n\t\treturn (request) -> \"POST\".equals(request.getMethod())\n\t\t\t\t&& request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) == null\n\t\t\t\t&& request.getParameter(OAuth2ParameterNames.REQUEST_URI) == null\n\t\t\t\t&& request.getParameter(OAuth2ParameterNames.REDIRECT_URI) == null\n\t\t\t\t&& request.getParameter(PkceParameterNames.CODE_CHALLENGE) == null\n\t\t\t\t&& request.getParameter(PkceParameterNames.CODE_CHALLENGE_METHOD) == null;\n\t}\n\n\tprivate static void throwError(String errorCode, String parameterName) {\n\t\tOAuth2Error error = new OAuth2Error(errorCode, \"OAuth 2.0 Parameter: \" + parameterName, DEFAULT_ERROR_URI);\n\t\tthrow new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);\n\t}\n\n}\n","sourceCodeStart":108,"sourceCodeEnd":130,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationConsentAuthenticationConverter.java#L108-L130","documentation":"OAuth2AuthorizationConsentAuthenticationConverter throws OAuth2AuthorizationCodeRequestAuthenticationException with description \"OAuth 2.0 Parameter: <parameterName>\" when a request to the authorization consent endpoint lacks required parameters (client_id and scope are mandatory) or carries malformed values. The converter validates the incoming consent/authorization request before it reaches the consent service, failing fast with the offending parameter in the error description.","triggerScenarios":"convert() calls throwError() when the consent endpoint request is missing client_id or scope, when the request method is not GET/POST as required, or when neither an authorization-consent payload nor a PKCE-eligible authorization code request is detectable (no code, code_challenge, or code_challenge_method parameters).","commonSituations":"A custom consent UI posts the consent form but omits the hidden client_id or scope inputs; a template renames form fields; a client submits consent without an active authorization transaction (no code/challenge parameters); version upgrades change which parameters the consent flow requires.","solutions":["Read the OAuth2Error description to see which parameter was flagged and include it in the consent request.","Ensure the consent form submits client_id and scope (one or more scope values) back to the consent endpoint.","Verify the consent page is only rendered/reached in the context of a valid authorization request that supplies code, code_challenge, or code_challenge_method parameters when PKCE is in play.","Use the default consent page (oauth2ConsentPage) or match its form field names exactly in a custom page."],"exampleFix":"// before: consent form missing required fields\n<form method=\"post\" action=\"/oauth2/consent\">\n  <button type=\"submit\">Approve</button>\n</form>\n// after\n<form method=\"post\" action=\"/oauth2/consent\">\n  <input type=\"hidden\" name=\"client_id\" th:value=\"${clientId}\"/>\n  <input type=\"hidden\" name=\"scope\" th:value=\"openid\"/>\n  <input type=\"hidden\" name=\"state\" th:value=\"${state}\"/>\n  <button type=\"submit\">Approve</button>\n</form>","handlingStrategy":"validation","validationCode":"function validateConsentSubmission(form) {\n  const errors = [];\n  if (!form.get('client_id')) errors.push('client_id is required');\n  if (!form.getAll('scope').length) errors.push('at least one scope is required');\n  return errors;\n}\nconst errs = validateConsentSubmission(new FormData(consentForm));\nif (errs.length) { alert('Fix form: ' + errs.join('; ')); return; }","typeGuard":"function isConsentFormComplete(f) {\n  return f instanceof FormData\n    && typeof f.get('client_id') === 'string' && f.get('client_id').length > 0\n    && f.getAll('scope').every(s => typeof s === 'string' && s.length > 0);\n}","tryCatchPattern":"try {\n  consentResult = submitConsent(clientId, scopes, state);\n} catch (OAuth2AuthorizationCodeRequestAuthenticationException e) {\n  OAuth2Error err = e.getError();\n  logger.warn(\"Consent request rejected: {}\", err.getDescription());\n  // re-render consent page with the flagged parameter highlighted\n}","preventionTips":["Include hidden client_id, scope, and state inputs in every custom consent form.","Reuse the default consent page template field names when building custom UIs.","Only reach the consent endpoint within an active authorization flow (authorization request in session or code/challenge params present).","Test consent flows end-to-end after upgrading Spring Authorization Server versions."],"tags":["oauth2","consent","request-validation","spring-security"],"backgroundTag":"missing-required-argument","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}