{"record":{"id":"a73bcff59b9aa9f5","repo":"apereo/cas","slug":"no-client-id-is-provided-in-the-request","errorCode":null,"errorMessage":"No client id is provided in the request","messagePattern":"No client id is provided in the request","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/validator/token/OAuth20PasswordGrantTypeTokenRequestValidator.java","lineNumber":45,"sourceCode":"    public OAuth20PasswordGrantTypeTokenRequestValidator(final ObjectProvider<OAuth20ConfigurationContext> configurationContext) {\n        super(configurationContext);\n    }\n\n    @Override\n    protected OAuth20GrantTypes getGrantType() {\n        return OAuth20GrantTypes.PASSWORD;\n    }\n\n    @Override\n    protected boolean validateInternal(final WebContext context, final String grantType,\n                                       final ProfileManager manager, final UserProfile uProfile) throws Throwable {\n\n        val configurationContext = getConfigurationContext().getObject();\n        val callContext = new CallContext(context, configurationContext.getSessionStore());\n        val clientIdAndSecret = configurationContext.getRequestParameterResolver().resolveClientIdAndClientSecret(callContext);\n        val clientId = StringUtils.defaultIfBlank(clientIdAndSecret.getKey(), (String) uProfile.getAttribute(OAuth20Constants.CLIENT_ID));\n        if (StringUtils.isBlank(clientId)) {\n            LOGGER.warn(\"No client id is provided in the request\");\n            return false;\n        }\n        LOGGER.debug(\"Received grant type [{}] with client id [{}]\", grantType, clientId);\n        val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(configurationContext.getServicesManager(), clientId);\n        RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(registeredService);\n        val service = configurationContext.getWebApplicationServiceServiceFactory().createService(registeredService.getServiceId());\n        val audit = AuditableContext.builder()\n            .service(service)\n            .registeredService(registeredService)\n            .build();\n        val accessResult = configurationContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit);\n        accessResult.throwExceptionIfNeeded();\n\n        if (!isGrantTypeSupportedBy(registeredService, grantType)) {\n            LOGGER.warn(\"Requested grant type [{}] is not authorized by service definition [{}]\",\n                grantType, registeredService.getServiceId());\n            return false;\n        }","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/validator/token/OAuth20PasswordGrantTypeTokenRequestValidator.java#L27-L63","documentation":"OAuth20PasswordGrantTypeTokenRequestValidator.validateInternal() requires a clientId resolved either from the request parameters (Basic auth header or form body) or from the authenticated user profile. If both are blank the validator logs this warning and returns false, rejecting the password-grant token request before looking up the registered service.","triggerScenarios":"A POST to the token endpoint with grant_type=password that omits client_id, omits the HTTP Basic Authorization header, and has no clientId attribute in the Pac4j user profile.","commonSituations":"Client sends only username/password without client credentials; Basic auth header malformed or stripped by a reverse proxy; client_id supplied under a misspelled parameter name; public-client setups that expect clientId to be optional.","solutions":["Include client_id as a request parameter or an HTTP Basic Authorization header in the token request.","Check that any reverse proxy does not strip the Authorization header before CAS receives it.","Verify the client library sends the parameter name exactly as `client_id` with a non-blank value.","If the client is supposed to be public, ensure the profile carries the CLIENT_ID attribute (client authenticated upstream)."],"exampleFix":"// before\ncurl -d 'grant_type=password&username=u&password=p' https://cas/oauth2.0/token\n// after\ncurl -u myClient:secret -d 'grant_type=password&username=u&password=p' https://cas/oauth2.0/token","handlingStrategy":"validation","validationCode":"const clientId = params.client_id || basicAuthUser || profile?.client_id;\nif (!clientId || !clientId.trim()) {\n  throw new Error('client_id required for password grant token request');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always send client_id or an HTTP Basic Authorization header on token requests","Verify reverse proxies forward the Authorization header","Add an integration test asserting the password-grant request includes client credentials"],"tags":["oauth","password-grant","missing-client-id","token-endpoint"],"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"}