public static LdapAuthenticationHandler createLdapAuthenticationHandler(final LdapAuthenticationProperties props,
                                                                            final ApplicationContext applicationContext,
                                                                            final ServicesManager servicesManager,
                                                                            final PrincipalFactory principalFactory) {
        val multiMapAttributes = CoreAuthenticationUtils.transformPrincipalAttributesListIntoMultiMap(props.getPrincipalAttributeList());
        LOGGER.debug("Created and mapped principal attributes [{}] for [{}]...", multiMapAttributes, props.getLdapUrl());

        LOGGER.debug("Creating LDAP authenticator for [{}] and baseDn [{}]", props.getLdapUrl(), props.getBaseDn());
        val authenticator = LdapUtils.newLdaptiveAuthenticator(props);
        LOGGER.debug("Ldap authenticator configured with return attributes [{}] for [{}] and baseDn [{}]",
            multiMapAttributes.keySet(), props.getLdapUrl(), props.getBaseDn());

        LOGGER.debug("Creating LDAP password policy handling strategy for [{}]", props.getLdapUrl());
        val strategy = createLdapPasswordPolicyHandlingStrategy(props, applicationContext);

        LOGGER.debug("Creating LDAP authentication handler for [{}]", props.getLdapUrl());
        val handler = new LdapAuthenticationHandler(props.getName(),
            servicesManager, principalFactory,
            props.getOrder(), authenticator, strategy);
        handler.setCollectDnAttribute(props.isCollectDnAttribute());

        if (!props.getAdditionalAttributes().isEmpty()) {
            val additional = CoreAuthenticationUtils.transformPrincipalAttributesListIntoMultiMap(props.getAdditionalAttributes());
            multiMapAttributes.putAll(additional);
        }

        FunctionUtils.doIfNotBlank(props.getPrincipalDnAttributeName(),
            __ -> handler.setPrincipalDnAttributeName(props.getPrincipalDnAttributeName()));
        handler.setAllowMultiplePrincipalAttributeValues(props.isAllowMultiplePrincipalAttributeValues());
        handler.setAllowMissingPrincipalAttributeValue(props.isAllowMissingPrincipalAttributeValue());
        handler.setPasswordEncoder(PasswordEncoderUtils.newPasswordEncoder(props.getPasswordEncoder(), applicationContext));
        handler.setPrincipalNameTransformer(PrincipalNameTransformerUtils.newPrincipalNameTransformer(props.getPrincipalTransformation()));

        if (StringUtils.isNotBlank(props.getCredentialCriteria())) {
            LOGGER.trace("Ldap authentication for [{}] is filtering credentials by [{}]", props.getLdapUrl(), props.getCredentialCriteria());
            handler.setCredentialSelectionPredicate(CoreAuthenticationUtils.newCredentialSelectionPredicate(props.getCredentialCriteria()));
        }

        if (StringUtils.isBlank(props.getPrincipalAttributeId())) {
            LOGGER.trace("No principal id attribute is found for LDAP authentication via [{}]", props.getLdapUrl());
        } else {
            handler.setPrincipalIdAttribute(props.getPrincipalAttributeId());
            LOGGER.trace("Using principal id attribute [{}] for LDAP authentication via [{}]",
                props.getPrincipalAttributeId(), props.getLdapUrl());
        }

        val passwordPolicy = props.getPasswordPolicy();
        if (passwordPolicy.isEnabled()) {
            LOGGER.trace("Password policy is enabled for [{}]. Constructing password policy configuration", props.getLdapUrl());
            val cfg = createLdapPasswordPolicyConfiguration(passwordPolicy, authenticator, multiMapAttributes);
            handler.setPasswordPolicyConfiguration(cfg);
        }

        val attributes = CollectionUtils.wrap(multiMapAttributes);
        handler.setPrincipalAttributeMap(attributes);

        LOGGER.debug("Initializing LDAP authentication handler for [{}]", props.getLdapUrl());
        handler.initialize();
        return handler;
    }
Create ldap authentication handler.

@param props              the ldap authentication properties
@param applicationContext the application context
@param servicesManager    the services manager
@param principalFactory   the principal factory
@return the ldap authentication handler
support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/util/LdapUtils.java