@Override
    @Audit(
        action = AuditableActions.AUTHENTICATION,
        actionResolverName = AuditActionResolvers.AUTHENTICATION_RESOLVER,
        resourceResolverName = AuditResourceResolvers.AUTHENTICATION_RESOURCE_RESOLVER)
    public Authentication authenticate(final AuthenticationTransaction transaction) throws Throwable {
        val result = invokeAuthenticationPreProcessors(transaction);
        if (!result) {
            LOGGER.warn("An authentication pre-processor could not successfully process the authentication transaction");
            throw new AuthenticationException("Authentication pre-processor has failed to process transaction");
        }
        val authenticationBuilder = authenticateInternal(transaction);
        val authentication = authenticationBuilder.build();
        addAuthenticationMethodAttribute(authenticationBuilder, authentication);
        populateAuthenticationMetadataAttributes(authenticationBuilder, transaction);
        invokeAuthenticationPostProcessors(authenticationBuilder, transaction);

        val auth = authenticationBuilder.build();
        val principal = auth.getPrincipal();
        if (principal instanceof NullPrincipal) {
            throw new UnresolvedPrincipalException(auth);
        }
        LOGGER.info("Authenticated principal [{}] with attributes [{}] via credentials [{}].",
            principal.getId(), principal.getAttributes(), transaction.getCredentials());
        return auth;
    }
This is {@link DefaultAuthenticationManager}, which provides common operations
around an authentication manager implementation.

@author Misagh Moayyed
@since 5.0.0
core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationManager.java