@Override
    protected void validateCredentials(final UsernamePasswordCredentials credentials,
                                       final OAuthRegisteredService registeredService,
                                       final CallContext callContext) {
        val clientSecret = getRequestParameterResolver().resolveClientIdAndClientSecret(callContext).getRight();
        if (!getClientSecretValidator().validate(registeredService, clientSecret)) {
            throw new CredentialsException("Client Credentials provided is not valid for service: " + registeredService.getName());
        }
        val codeVerifier = getRequestParameterResolver()
            .resolveRequestParameter(callContext.webContext(), OAuth20Constants.CODE_VERIFIER)
            .map(String::valueOf).orElse(StringUtils.EMPTY);
        val code = getRequestParameterResolver()
            .resolveRequestParameter(callContext.webContext(), OAuth20Constants.CODE)
            .map(String::valueOf).orElse(StringUtils.EMPTY);

        LOGGER.debug("Received PKCE code verifier [{}] along with code [{}]", codeVerifier, code);
        val token = getTicketRegistry().getTicket(code, OAuth20Code.class);
        if (token == null || token.isExpired()) {
            LOGGER.error("Provided code [{}] is either not found in the ticket registry or has expired", code);
            throw new CredentialsException("Invalid token: " + code);
        }

        val method = StringUtils.defaultIfEmpty(token.getCodeChallengeMethod(), "plain");
        val hash = calculateCodeVerifierHash(method, codeVerifier);
        if (!hash.equalsIgnoreCase(token.getCodeChallenge())) {
            LOGGER.error("Code verifier [{}] does not match the challenge [{}]", hash, token.getCodeChallenge());
            throw new CredentialsException("Code verification does not match the challenge assigned to: " + token.getId());
        }
        LOGGER.debug("Validated code verifier using verification method [{}]", method);
    }
This is {@link OAuth20ProofKeyCodeExchangeAuthenticator}.

@author Misagh Moayyed
@since 6.0.0
support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/authenticator/OAuth20ProofKeyCodeExchangeAuthenticator.java