apereo/cas · warning
CAS is configured to only accept pushed authorization…
Error message
CAS is configured to only accept pushed authorization requests and this is not a POST
What it means
CAS's OIDC request interceptor rejects non-POST authorization requests when 'requirePushedAuthorizationRequests' is enabled, unless the request uses a request_uri (i.e. an already-pushed request). Per JAR/PAR, when this mode is on, clients must first POST parameters to the pushed authorization request endpoint and then hit /authorize with only request_uri. This is a deliberate rejection (HTTP 403) enforced in OidcHandlerInterceptorAdapter.preHandle.
Solutions
- Update all relying parties to POST authorization parameters to the PAR endpoint (/oidc/pushAuthRequest or similar) and then redirect to /authorize with the returned request_uri
- Set cas.authn.oidc.discovery.require-pushed-authorization-requests=false if you do not actually need PAR
- Verify the request carries a non-blank request_uri parameter if it is a follow-up authorize call
- Upgrade the RP's OIDC client library to one supporting RFC 9126 PAR
Example fix
// before
GET /oidc/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=...
// after
POST /oidc/pushAuthRequest (response_type=code&client_id=client&...) -> {"request_uri":"urn:ietf:params:oauth:request_uri:..."}
GET /oidc/authorize?client_id=client&request_uri=urn:ietf:params:oauth:request_uri:... Defensive patterns
Strategy: validation
Validate before calling
const isParMode = casProperties.authn.oidc.discovery.requirePushedAuthorizationRequests;
const isAuthorizeWithUri = url.searchParams.get('request_uri')?.trim() !== '';
if (isParMode && method !== 'POST' && !isAuthorizeWithUri) throw new Error('PAR required: POST parameters to the PAR endpoint first'); Type guard
function hasRequestUri(params) {
return typeof params.request_uri === 'string' && params.request_uri.trim().length > 0;
} Prevention
- Read discovery metadata and honor require_pushed_authorization_requests
- Implement the PAR POST step in the RP before redirecting to /authorize
- Test the full PAR -> authorize flow after enabling the mode
- Keep request_uri intact through redirects (it is short-lived)
When it happens
Trigger: A GET to the OIDC /authorize endpoint (or any non-POST authorize request) while cas.authn.oidc.discovery.require-pushed-authorization-requests=true, the request has no 'request_uri' parameter, and it looks like an authorization request.
Common situations: Deployers flip on requirePushedAuthorizationRequests but existing client applications still perform plain GET-based browser redirects to /authorize; legacy clients or tutorials that never adopted PAR; misconfigured RP libraries that ignore the 'require_pushed_authorization_requests' discovery flag.
Related errors
- CAS is configured to only accept pushed authorization…
- Invalid OIDC pushed authorization request at
- Resource-set owner does not match the authenticated profile
- JWKS cannot contain expressions
- Unable to use 'none' as introspection signing algorithm
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/216616d8c6d3749f.
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:69
oauthRequestParameterResolver);
this.requiresAuthenticationDynamicRegistrationInterceptor = requiresAuthenticationDynamicRegistrationInterceptor;
this.casProperties = casProperties;
this.requiresAuthenticationClientConfigurationInterceptor = requiresAuthenticationClientConfigurationInterceptor;
}
@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response,
final Object handler) throws Exception {
LOGGER.trace("Attempting to pre-handle OIDC request at [{}] with parameters [{}]",
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())) {View on GitHub (pinned to e7288fc434)