@Override
    public Optional<Credentials> validate(final CallContext ctx, final Credentials credentials) {
        val clientIdAndSecret = requestParameterResolver.resolveClientIdAndClientSecret(ctx);
        val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(servicesManager, clientIdAndSecret.getKey());
        RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(registeredService);

        if (!isAuthenticationMethodSupported(ctx, registeredService)) {
            LOGGER.warn("TLS authentication method is not supported for service [{}]", registeredService.getName());
            return Optional.empty();
        }

        val allowedSubjectPattern = StringUtils.defaultIfBlank(registeredService.getTlsClientAuthSubjectDn(), "CN=(.*?)(?:,|$)");
        val x509Authenticator = new X509Authenticator(allowedSubjectPattern);
        val result = x509Authenticator.validate(ctx, credentials);
        if (result.isPresent()) {
            val profile = result.get().getUserProfile();
            val certificate = ((X509Credentials) credentials).getCertificate();
            val digest = EncodingUtils.encodeBase64(DigestUtils.digest("SHA-256", certificate.getPublicKey().getEncoded()));
            profile.addAttribute(OAuth20Constants.X509_CERTIFICATE_DIGEST, digest);
            profile.addAttribute(AuthenticationManager.AUTHENTICATION_METHOD_ATTRIBUTE, "X.509");
            profile.addAttribute(OAuth20Constants.CLIENT_ID, clientIdAndSecret.getKey());
            
            val attributeMap = CollectionUtils.<String, String>wrap(
                "x509-sanEmail", registeredService.getTlsClientAuthSanEmail(),
                "x509-sanDNS", registeredService.getTlsClientAuthSanDns(),
                "x509-sanIP", registeredService.getTlsClientAuthSanIp(),
                "x509-sanURI", registeredService.getTlsClientAuthSanUri()
            );
            val accepted = attributeMap
                .entrySet()
                .stream()
                .allMatch(entry -> isAcceptableX509Attribute(profile, entry.getKey(), entry.getValue()));
            if (!accepted) {
                throw new CredentialsException("Unable to accept certificate");
            }
        }

        return result;
    }
This is {@link OAuth20X509Authenticator}.

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