apereo/cas · warning

Invalid OIDC pushed authorization request at

Error message

Invalid OIDC pushed authorization request at [{}]

What it means

CAS received a pushed authorization request (POST to the PAR endpoint) but its contents failed authorization-request validation (isValidAuthorizeRequest). The interceptor responds 403 with an error body. This validates that the pushed parameters constitute a well-formed OAuth2/OIDC authorize request (client_id, response_type, redirect_uri, etc.).

Solutions

  1. Inspect the CAS debug logs and ensure the POSTed parameters form a complete valid authorize request (client_id, response_type=code, scope containing openid, redirect_uri matching a registered service exactly)
  2. Verify the client_id corresponds to an enabled OIDC-registered service in CAS
  3. Fix the RP client to send all required parameters in the PAR POST
  4. Test with a minimal curl POST replicating the exact parameters to isolate the invalid field

Example fix

// before
POST /oidc/pushAuthRequest  body: client_id=client&response_type=code   (missing redirect_uri/scope)
// after
POST /oidc/pushAuthRequest  body: client_id=client&response_type=code&scope=openid&redirect_uri=https://rp.example.org/cb
Defensive patterns

Strategy: validation

Validate before calling

const required = ['response_type','client_id','redirect_uri','scope'];
const missing = required.filter(p => !parBody.has(p));
if (missing.length) throw new Error(`PAR payload missing: ${missing.join(',')}`);
if (!parBody.get('scope').split(' ').includes('openid')) throw new Error('openid scope required');

Type guard

function isValidParPayload(body) {
  return body.has('response_type') && body.has('client_id') &&
         body.has('redirect_uri') && body.has('scope');
}

Prevention

When it happens

Trigger: POST to the OIDC PAR endpoint where the payload is missing required authorize parameters (client_id, response_type, redirect_uri), has invalid values, or otherwise fails OAuth20Validator-based authorize validation.

Common situations: Clients POSTing incomplete parameter sets; redirect_uri not exactly matching a registered service; response_type not 'code'; client not registered or disabled; missing 'openid' scope handling quirks; parameter encoding bugs in RP libraries.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/5b061694cb38d2d3. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/OidcHandlerInterceptorAdapter.java:81

            request.getRequestURI(), request.getParameterMap().keySet());

        if (casProperties.getAuthn().getOidc().getDiscovery().isRequirePushedAuthorizationRequests()
            && !HttpMethod.valueOf(request.getMethod()).equals(HttpMethod.POST)
            && StringUtils.isBlank(request.getParameter(OidcConstants.REQUEST_URI))
            && isAuthorizationRequest(request, response)) {
            LOGGER.warn("CAS is configured to only accept pushed authorization requests and this is not a POST");
            response.setStatus(HttpStatus.SC_FORBIDDEN);
            return false;
        }

        if (!isDynamicClientRegistrationEnabled() && (isClientConfigurationRequest(request.getRequestURI()) || isDynamicClientRegistrationRequest(request.getRequestURI()))) {
            LOGGER.debug("Dynamic client registration is disabled. OIDC request at [{}] is rejected.", request.getRequestURI());
            response.setStatus(HttpStatus.SC_NOT_IMPLEMENTED);
            return false;
        }

        if (isPushedAuthorizationRequest(request.getRequestURI()) && !isValidAuthorizeRequest(new JEEContext(request, response))) {
            LOGGER.warn("Invalid OIDC pushed authorization request at [{}]", request.getRequestURI());
            response.setStatus(HttpStatus.SC_FORBIDDEN);
            writeErrorResponseBody(response);
            return false;
        }

        if (isVerifiableCredentialTransactionRequest(request.getRequestURI()) || isPushedAuthorizationRequest(request.getRequestURI())) {
            LOGGER.trace("OIDC request is protected at [{}]", request.getRequestURI());
            return requiresAuthenticationAccessTokenInterceptor.getObject().preHandle(request, response, handler);
        }

        if (isCibaRequest(request.getRequestURI())) {
            LOGGER.trace("OIDC CIBA request is protected at [{}]", request.getRequestURI());
            return requiresAuthenticationAccessTokenInterceptor.getObject().preHandle(request, response, handler);
        }

        if (!super.preHandle(request, response, handler)) {
            LOGGER.trace("Unable to pre-handle OIDC request at [{}]", request.getRequestURI());
            return false;

View on GitHub (pinned to e7288fc434)