{"record":{"id":"41bbd288c09b87ed","repo":"apereo/cas","slug":"provided-scopes-are-undefined-by-openid-conne","errorCode":null,"errorMessage":"Provided scopes [{}] are undefined by OpenID Connect, which requires that scope [{}] MUST be specified, or the behavior is unspecified. CAS MAY allow this request to be processed for now.","messagePattern":"Provided scopes \\[(.+?)\\] are undefined by OpenID Connect, which requires that scope \\[(.+?)\\] MUST be specified, or the behavior is unspecified\\. CAS MAY allow this request to be processed for now\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/controllers/authorize/OidcAuthorizeEndpointController.java","lineNumber":57,"sourceCode":"    @Operation(summary = \"Handle OIDC authorization request\")\n    @Override\n    public ModelAndView handleRequest(final HttpServletRequest request, final HttpServletResponse response) throws Throwable {\n        val webContext = new JEEContext(request, response);\n        if (!getConfigurationContext().getIssuerService().validateIssuer(webContext, List.of(OidcConstants.AUTHORIZE_URL, OAuth20Constants.AUTHORIZE_URL))) {\n            LOGGER.warn(\"CAS cannot accept the authorization request given the issuer is invalid.\");\n            return OAuth20Utils.writeError(response, OAuth20Constants.INVALID_REQUEST, \"Invalid issuer\");\n        }\n\n        if (getConfigurationContext().getDiscoverySettings().isRequirePushedAuthorizationRequests()\n            && webContext.getRequestURL().endsWith(OidcConstants.AUTHORIZE_URL)\n            && StringUtils.isBlank(request.getParameter(OidcConstants.REQUEST_URI))) {\n            LOGGER.warn(\"CAS is configured to only accept pushed authorization requests\");\n            return OAuth20Utils.produceUnauthorizedErrorView(HttpStatus.FORBIDDEN);\n        }\n\n        val scopes = getConfigurationContext().getRequestParameterResolver().resolveRequestedScopes(webContext);\n        if (scopes.isEmpty() || !scopes.contains(OidcConstants.StandardScopes.OPENID.getScope())) {\n            LOGGER.warn(\"Provided scopes [{}] are undefined by OpenID Connect, which requires that scope [{}] MUST be specified, \"\n                        + \"or the behavior is unspecified. CAS MAY allow this request to be processed for now.\",\n                scopes, OidcConstants.StandardScopes.OPENID.getScope());\n        }\n        return super.handleRequest(request, response);\n    }\n\n    @PostMapping({\n        '/' + OidcConstants.BASE_OIDC_URL + '/' + OAuth20Constants.AUTHORIZE_URL,\n        \"/**/\" + OidcConstants.AUTHORIZE_URL\n    })\n    @Override\n    @Operation(summary = \"Handle OIDC authorization request\")\n    public ModelAndView handleRequestPost(final HttpServletRequest request,\n                                          final HttpServletResponse response) throws Throwable {\n        return handleRequest(request, response);\n    }\n}\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/controllers/authorize/OidcAuthorizeEndpointController.java#L39-L75","documentation":"The OIDC specification requires that every authorization request include the 'openid' scope. CAS resolves the requested scopes and logs a warning if the scope set is empty or lacks 'openid'; it does not hard-fail (the spec says CAS MAY still process the request). This is a compliance warning, not a rejection.","triggerScenarios":"Any authorization request (or PAR request reaching authorize) whose resolved scope list is empty or does not contain the 'openid' scope, e.g. scope=profile email or no scope at all.","commonSituations":"RP libraries defaulting to plain OAuth2 scope requests; developers testing with only 'profile'; clients copying OAuth2 examples that omit scope; PAR flows dropping the scope parameter.","solutions":["Add 'openid' to the scope parameter of the authorization request","Ensure the RP library defaults include the openid scope for OIDC flows","Keep scope values space-delimited and URL-encoded properly (scope=openid%20profile)","If purely OAuth2 (non-OIDC) usage is intended, use the plain /oauth2.0/authorize endpoint instead"],"exampleFix":"// before\nGET /oidc/authorize?client_id=client&response_type=code&scope=profile&redirect_uri=...\n// after\nGET /oidc/authorize?client_id=client&response_type=code&scope=openid%20profile&redirect_uri=...","handlingStrategy":"validation","validationCode":"const scopes = (params.get('scope') ?? '').split(' ').filter(Boolean);\nif (!scopes.includes('openid')) throw new Error('OIDC authorization requests must include scope \"openid\"');","typeGuard":"function hasOpenIdScope(scopeStr) {\n  return typeof scopeStr === 'string' && scopeStr.split(' ').includes('openid');\n}","tryCatchPattern":null,"preventionTips":["Always prepend 'openid' to the scope list in OIDC clients","Check RP library defaults for scope","Use space-delimited, URL-encoded scope values","Use /oauth2.0 endpoints for pure OAuth2 flows without openid"],"tags":["oidc","scope","openid","compliance"],"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"}