@Override
    public Optional<Credentials> validate(final CallContext callContext, final Credentials credentials) {
        val tokenCredentials = (TokenCredentials) credentials;
        val token = extractAccessTokenFrom(tokenCredentials);
        LOGGER.trace("Received access token [{}] for authentication", token);

        val accessToken = ticketRegistry.getTicket(token, OAuth20AccessToken.class);
        if (accessToken == null || accessToken.isExpired()) {
            LOGGER.error("Provided access token [{}] is either not found in the ticket registry or has expired", token);
            return Optional.empty();
        }

        if (!requiredScopes.isEmpty() && !accessToken.getScopes().containsAll(requiredScopes)) {
            LOGGER.error("Unable to authenticate access token without required scopes [{}]", requiredScopes);
            return Optional.empty();
        }

        val profile = buildUserProfile(tokenCredentials, callContext, accessToken);
        if (profile != null) {
            LOGGER.trace("Final user profile based on access token [{}] is [{}]", accessToken, profile);
            tokenCredentials.setUserProfile(profile);
            return Optional.of(tokenCredentials);
        }
        return Optional.empty();
    }
This is {@link OAuth20AccessTokenAuthenticator}.

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