apereo/cas · error · CredentialsException

No client credentials could be identified in this request

Error message

No client credentials could be identified in this request

What it means

Thrown during username/password profile validation in the OAuth authenticator when resolveClientIdAndClientSecret finds no client_id in the request (no basic auth header and no client_id parameter). The authenticator needs both the end-user credentials and an identifiable OAuth client to proceed.

Solutions

  1. Include client_id (and client_secret) as request parameters or send them via HTTP Basic auth in the same request
  2. Confirm the OAuth client is registered so a valid client_id is actually accepted by the parameter resolver
  3. Check that no proxy/filter strips the Authorization header or query/body parameters before they reach CAS
  4. Match the exact parameter name expected by the configured request parameter resolver

Example fix

// before
POST /cas/oauth2.0/token  username=user&password=pass
// after
POST /cas/oauth2.0/token  username=user&password=pass&client_id=myclient&client_secret=secret
Defensive patterns

Strategy: validation

Validate before calling

if (!clientId) throw new Error('client_id is required (body param or Basic auth) before calling the CAS OAuth endpoint');

Type guard

const hasClientCredentials = (p) => typeof p.client_id === 'string' && p.client_id.length > 0;

Prevention

When it happens

Trigger: POSTing username/password (grant_type=password style flow) without a client_id request parameter and without HTTP Basic credentials; the parameter resolver returns a blank key and the authenticator aborts before looking up the registered service.

Common situations: Frontend omitted client_id from the token/login request; a gateway strips the Authorization header; client sending credentials only as username/password while CAS requires client identification too; typo in parameter name (clientId vs client_id).

Related errors


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

Appendix: source

Thrown at support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/authenticator/OAuth20UsernamePasswordAuthenticator.java:72

    private final OAuth20ClientSecretValidator clientSecretValidator;

    private final AuthenticationAttributeReleasePolicy authenticationAttributeReleasePolicy;

    private final OAuth20ProfileScopeToAttributesFilter profileScopeToAttributesFilter;

    private final TicketFactory ticketFactory;

    private final ConfigurableApplicationContext applicationContext;

    @Override
    public Optional<Credentials> validate(final CallContext callContext, final Credentials credentials) throws CredentialsException {
        try {
            val upc = (UsernamePasswordCredentials) credentials;
            val casCredential = new UsernamePasswordCredential(upc.getUsername(), upc.getPassword());
            val clientIdAndSecret = requestParameterResolver.resolveClientIdAndClientSecret(callContext);
            if (StringUtils.isBlank(clientIdAndSecret.getKey())) {
                throw new CredentialsException("No client credentials could be identified in this request");
            }

            val clientId = clientIdAndSecret.getKey();
            val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(servicesManager, clientId);
            RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(registeredService);

            val clientSecret = clientIdAndSecret.getRight();
            if (!clientSecretValidator.validate(registeredService, clientSecret)) {
                throw new CredentialsException("Client Credentials provided is not valid for registered service: "
                    + Objects.requireNonNull(registeredService).getName());
            }
            val redirectUri = requestParameterResolver.resolveRequestParameter(callContext.webContext(), OAuth20Constants.REDIRECT_URI)
                .map(String::valueOf).orElse(StringUtils.EMPTY);
            OAuth20Utils.validateRedirectUri(redirectUri, true);
            val service = StringUtils.isNotBlank(redirectUri)
                ? webApplicationServiceFactory.createService(redirectUri)
                : webApplicationServiceFactory.createService(clientId);
            service.getAttributes().put(OAuth20Constants.CLIENT_ID, CollectionUtils.wrapList(clientId));

View on GitHub (pinned to e7288fc434)