/******************************************************************************* * Cloud Foundry * Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. *******************************************************************************/ package org.cloudfoundry.identity.uaa.provider; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.util.StringUtils; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) public class LdapIdentityProviderDefinition extends ExternalIdentityProviderDefinition { public static final String LDAP_TLS_NONE = "none"; public static final String LDAP_TLS_SIMPLE = "simple"; public static final String LDAP_TLS_EXTERNAL = "external"; public static final String LDAP = OriginKeys.LDAP; public static final String LDAP_PREFIX = LDAP + "."; public static final String LDAP_ATTRIBUTE_MAPPINGS = LDAP_PREFIX + ATTRIBUTE_MAPPINGS; public static final String LDAP_BASE_LOCAL_PASSWORD_COMPARE = LDAP_PREFIX + "base.localPasswordCompare"; public static final String LDAP_BASE_MAIL_ATTRIBUTE_NAME = LDAP_PREFIX + "base.mailAttributeName"; public static final String LDAP_BASE_MAIL_SUBSTITUTE = LDAP_PREFIX + "base.mailSubstitute"; public static final String LDAP_BASE_MAIL_SUBSTITUTE_OVERRIDES_LDAP = LDAP_PREFIX + "base.mailSubstituteOverridesLdap"; public static final String LDAP_BASE_PASSWORD = LDAP_PREFIX + "base.password"; public static final String LDAP_BASE_PASSWORD_ATTRIBUTE_NAME = LDAP_PREFIX + "base.passwordAttributeName"; public static final String LDAP_BASE_PASSWORD_ENCODER = LDAP_PREFIX + "base.passwordEncoder"; public static final String LDAP_BASE_REFERRAL = LDAP_PREFIX + "base.referral"; public static final String LDAP_BASE_SEARCH_BASE = LDAP_PREFIX + "base.searchBase"; public static final String LDAP_BASE_SEARCH_FILTER = LDAP_PREFIX + "base.searchFilter"; public static final String LDAP_BASE_URL = LDAP_PREFIX + "base.url"; public static final String LDAP_BASE_USER_DN = LDAP_PREFIX + "base.userDn"; public static final String LDAP_BASE_USER_DN_PATTERN = LDAP_PREFIX + "base.userDnPattern"; public static final String LDAP_BASE_USER_DN_PATTERN_DELIMITER = LDAP_PREFIX + "base.userDnPatternDelimiter"; public static final String LDAP_EMAIL_DOMAIN = LDAP_PREFIX + EMAIL_DOMAIN_ATTR; public static final String LDAP_STORE_CUSTOM_ATTRIBUTES = LDAP_PREFIX + STORE_CUSTOM_ATTRIBUTES_NAME; public static final String LDAP_EXTERNAL_GROUPS_WHITELIST = LDAP_PREFIX + "externalGroupsWhitelist"; public static final String LDAP_GROUP_FILE_GROUPS_AS_SCOPES = "ldap/ldap-groups-as-scopes.xml"; public static final String LDAP_GROUP_FILE_GROUPS_MAP_TO_SCOPES = "ldap/ldap-groups-map-to-scopes.xml"; public static final String LDAP_GROUP_FILE_GROUPS_NULL_XML = "ldap/ldap-groups-null.xml"; public static final String LDAP_GROUPS_AUTO_ADD = LDAP_PREFIX + "groups.autoAdd"; public static final String LDAP_GROUPS_FILE = LDAP_PREFIX + "groups.file"; public static final String LDAP_GROUPS_GROUP_ROLE_ATTRIBUTE = LDAP_PREFIX + "groups.groupRoleAttribute"; public static final String LDAP_GROUPS_GROUP_SEARCH_FILTER = LDAP_PREFIX + "groups.groupSearchFilter"; public static final String LDAP_GROUPS_IGNORE_PARTIAL_RESULT_EXCEPTION = LDAP_PREFIX + "groups.ignorePartialResultException"; public static final String LDAP_GROUPS_MAX_SEARCH_DEPTH = LDAP_PREFIX + "groups.maxSearchDepth"; public static final String LDAP_GROUPS_SEARCH_BASE = LDAP_PREFIX + "groups.searchBase"; public static final String LDAP_GROUPS_SEARCH_SUBTREE = LDAP_PREFIX + "groups.searchSubtree"; public static final String LDAP_PROFILE_FILE = LDAP_PREFIX + "profile.file"; public static final String LDAP_PROFILE_FILE_SEARCH_AND_BIND = "ldap/ldap-search-and-bind.xml"; public static final String LDAP_PROFILE_FILE_SEARCH_AND_COMPARE = "ldap/ldap-search-and-compare.xml"; public static final String LDAP_PROFILE_FILE_SIMPLE_BIND = "ldap/ldap-simple-bind.xml"; public static final String LDAP_SSL_SKIPVERIFICATION = LDAP_PREFIX + "ssl.skipverification"; public static final String LDAP_SSL_TLS = LDAP_PREFIX + "ssl.tls"; public static final String MAIL = "mail"; public static final List<String> VALID_PROFILE_FILES = Collections.unmodifiableList( Arrays.asList( "ldap/ldap-search-and-bind.xml", "ldap/ldap-search-and-compare.xml", "ldap/ldap-simple-bind.xml" ) ); public static final List<String> VALID_GROUP_FILES = Collections.unmodifiableList( Arrays.asList( "ldap/ldap-groups-as-scopes.xml", "ldap/ldap-groups-map-to-scopes.xml", "ldap/ldap-groups-null.xml", "ldap/ldap-groups-populator.xml" ) ); public static final List<String> LDAP_PROPERTY_NAMES = Collections.unmodifiableList( Arrays.asList( LDAP_ATTRIBUTE_MAPPINGS, LDAP_BASE_LOCAL_PASSWORD_COMPARE, LDAP_BASE_MAIL_ATTRIBUTE_NAME, LDAP_BASE_MAIL_SUBSTITUTE, LDAP_BASE_MAIL_SUBSTITUTE_OVERRIDES_LDAP, LDAP_BASE_PASSWORD, LDAP_BASE_PASSWORD_ATTRIBUTE_NAME, LDAP_BASE_PASSWORD_ENCODER, LDAP_BASE_REFERRAL, LDAP_BASE_SEARCH_BASE, LDAP_BASE_SEARCH_FILTER, LDAP_BASE_URL, LDAP_BASE_USER_DN, LDAP_BASE_USER_DN_PATTERN, LDAP_BASE_USER_DN_PATTERN_DELIMITER, LDAP_EMAIL_DOMAIN, LDAP_EXTERNAL_GROUPS_WHITELIST, LDAP_GROUPS_AUTO_ADD, LDAP_GROUPS_FILE, LDAP_GROUPS_GROUP_ROLE_ATTRIBUTE, LDAP_GROUPS_GROUP_SEARCH_FILTER, LDAP_GROUPS_IGNORE_PARTIAL_RESULT_EXCEPTION, LDAP_GROUPS_MAX_SEARCH_DEPTH, LDAP_GROUPS_SEARCH_BASE, LDAP_GROUPS_SEARCH_SUBTREE, LDAP_PROFILE_FILE, LDAP_SSL_SKIPVERIFICATION, LDAP_SSL_TLS ) ); public static final Map<String, Class<?>> LDAP_PROPERTY_TYPES = new HashMap<>(); static { LDAP_PROPERTY_TYPES.put(LDAP_ATTRIBUTE_MAPPINGS, Map.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_LOCAL_PASSWORD_COMPARE, Boolean.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_MAIL_ATTRIBUTE_NAME, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_MAIL_SUBSTITUTE, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_MAIL_SUBSTITUTE_OVERRIDES_LDAP, Boolean.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_PASSWORD, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_PASSWORD_ATTRIBUTE_NAME, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_PASSWORD_ENCODER, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_REFERRAL, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_SEARCH_BASE, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_SEARCH_FILTER, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_URL, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_USER_DN, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_USER_DN_PATTERN, String.class); LDAP_PROPERTY_TYPES.put(LDAP_BASE_USER_DN_PATTERN_DELIMITER, String.class); LDAP_PROPERTY_TYPES.put(LDAP_EMAIL_DOMAIN, List.class); LDAP_PROPERTY_TYPES.put(LDAP_EXTERNAL_GROUPS_WHITELIST, List.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_AUTO_ADD, Boolean.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_FILE, String.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_GROUP_ROLE_ATTRIBUTE, String.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_GROUP_SEARCH_FILTER, String.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_IGNORE_PARTIAL_RESULT_EXCEPTION, Boolean.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_MAX_SEARCH_DEPTH, Integer.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_SEARCH_BASE, String.class); LDAP_PROPERTY_TYPES.put(LDAP_GROUPS_SEARCH_SUBTREE, Boolean.class); LDAP_PROPERTY_TYPES.put(LDAP_PROFILE_FILE, String.class); LDAP_PROPERTY_TYPES.put(LDAP_SSL_SKIPVERIFICATION, Boolean.class); LDAP_PROPERTY_TYPES.put(LDAP_SSL_TLS, String.class); } private String ldapProfileFile; private String baseUrl; private String referral; private Boolean skipSSLVerification; private String userDNPattern; private String userDNPatternDelimiter; private String bindUserDn; private String bindPassword; private String userSearchBase; private String userSearchFilter; private String passwordAttributeName; private String passwordEncoder; private Boolean localPasswordCompare; private String mailAttributeName = MAIL; private String mailSubstitute; private Boolean mailSubstituteOverridesLdap = false; private String ldapGroupFile = null; private String groupSearchBase; private String groupSearchFilter; private Boolean groupsIgnorePartialResults; private Boolean autoAddGroups = true; private Boolean groupSearchSubTree = true; private int maxGroupSearchDepth = 10; private String groupRoleAttribute; private String tlsConfiguration = LDAP_TLS_NONE; public static LdapIdentityProviderDefinition searchAndBindMapGroupToScopes( String baseUrl, String bindUserDn, String bindPassword, String userSearchBase, String userSearchFilter, String groupSearchBase, String groupSearchFilter, String mailAttributeName, String mailSubstitute, Boolean mailSubstituteOverridesLdap, Boolean autoAddGroups, Boolean groupSearchSubTree, int groupMaxSearchDepth, Boolean skipSSLVerification) { LdapIdentityProviderDefinition definition = new LdapIdentityProviderDefinition(); definition.baseUrl = baseUrl; definition.bindUserDn = bindUserDn; definition.bindPassword = bindPassword; definition.userSearchBase = userSearchBase; definition.userSearchFilter = userSearchFilter; definition.groupSearchBase = groupSearchBase; definition.groupSearchFilter = groupSearchFilter; definition.mailAttributeName = mailAttributeName; definition.mailSubstitute = mailSubstitute; definition.ldapProfileFile = LDAP_PROFILE_FILE_SEARCH_AND_BIND; definition.ldapGroupFile = LDAP_GROUP_FILE_GROUPS_MAP_TO_SCOPES; definition.mailSubstituteOverridesLdap = mailSubstituteOverridesLdap; definition.autoAddGroups = autoAddGroups; definition.groupSearchSubTree = groupSearchSubTree; definition.maxGroupSearchDepth = groupMaxSearchDepth; definition.skipSSLVerification = skipSSLVerification; return definition; } public String getReferral() { return referral; } public void setReferral(String referral) { this.referral = referral; } public Boolean isAutoAddGroups() { return autoAddGroups; } public String getBaseUrl() { return baseUrl; } @JsonInclude(JsonInclude.Include.NON_NULL) public String getBindPassword() { return bindPassword; } public String getBindUserDn() { return bindUserDn; } public String getGroupSearchBase() { return groupSearchBase; } public String getGroupSearchFilter() { return groupSearchFilter; } public String getLdapGroupFile() { return ldapGroupFile; } public String getLdapProfileFile() { return ldapProfileFile; } public String getMailAttributeName() { return mailAttributeName; } public String getMailSubstitute() { return mailSubstitute; } public Boolean isMailSubstituteOverridesLdap() { return mailSubstituteOverridesLdap == null ? false : mailSubstituteOverridesLdap; } public String getUserSearchBase() { return userSearchBase; } public String getUserSearchFilter() { return userSearchFilter; } public Boolean isGroupSearchSubTree() { return groupSearchSubTree; } public int getMaxGroupSearchDepth() { return maxGroupSearchDepth; } public Boolean isSkipSSLVerification() { return skipSSLVerification == null ? false : skipSSLVerification; } public void setAutoAddGroups(Boolean autoAddGroups) { this.autoAddGroups = autoAddGroups; } public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; } public void setBindPassword(String bindPassword) { this.bindPassword = bindPassword; } public void setBindUserDn(String bindUserDn) { this.bindUserDn = bindUserDn; } public void setGroupSearchBase(String groupSearchBase) { this.groupSearchBase = groupSearchBase; } public void setGroupSearchFilter(String groupSearchFilter) { this.groupSearchFilter = groupSearchFilter; } public void setGroupSearchSubTree(Boolean groupSearchSubTree) { this.groupSearchSubTree = groupSearchSubTree; } public void setLdapGroupFile(String ldapGroupFile) { if (ldapGroupFile != null && !VALID_GROUP_FILES.contains(ldapGroupFile)) { throw new IllegalArgumentException("Invalid profile file:" + ldapGroupFile); } this.ldapGroupFile = ldapGroupFile; } public void setLdapProfileFile(String ldapProfileFile) { if (ldapProfileFile != null && !VALID_PROFILE_FILES.contains(ldapProfileFile)) { throw new IllegalArgumentException("Invalid profile file:" + ldapProfileFile); } this.ldapProfileFile = ldapProfileFile; } public void setMailAttributeName(String mailAttributeName) { this.mailAttributeName = mailAttributeName; } public void setMailSubstitute(String mailSubstitute) { this.mailSubstitute = mailSubstitute; } public void setMailSubstituteOverridesLdap(Boolean mailSubstituteOverridesLdap) { this.mailSubstituteOverridesLdap = mailSubstituteOverridesLdap; } public void setMaxGroupSearchDepth(int maxGroupSearchDepth) { this.maxGroupSearchDepth = maxGroupSearchDepth; } public void setSkipSSLVerification(Boolean skipSSLVerification) { this.skipSSLVerification = skipSSLVerification; } public void setUserSearchBase(String userSearchBase) { this.userSearchBase = userSearchBase; } public void setUserSearchFilter(String userSearchFilter) { this.userSearchFilter = userSearchFilter; } public String getUserDNPattern() { return userDNPattern; } public void setUserDNPattern(String userDNPattern) { this.userDNPattern = userDNPattern; } public String getPasswordAttributeName() { return passwordAttributeName; } public void setPasswordAttributeName(String passwordAttributeName) { this.passwordAttributeName = passwordAttributeName; } public String getPasswordEncoder() { return passwordEncoder; } public void setPasswordEncoder(String passwordEncoder) { if (passwordEncoder == null || "org.cloudfoundry.identity.uaa.provider.ldap.DynamicPasswordComparator".equals(passwordEncoder)) { this.passwordEncoder = passwordEncoder; } else { throw new IllegalArgumentException("Unknown encoder:" + passwordEncoder); } } public String getGroupRoleAttribute() { return groupRoleAttribute; } public void setGroupRoleAttribute(String groupRoleAttribute) { this.groupRoleAttribute = groupRoleAttribute; } @JsonIgnore public Boolean isConfigured() { return StringUtils.hasText(getBaseUrl()); } public Boolean isLocalPasswordCompare() { return localPasswordCompare; } public void setLocalPasswordCompare(Boolean localPasswordCompare) { this.localPasswordCompare = localPasswordCompare; } public String getUserDNPatternDelimiter() { return userDNPatternDelimiter; } public void setUserDNPatternDelimiter(String userDNPatternDelimiter) { this.userDNPatternDelimiter = userDNPatternDelimiter; } public Boolean isGroupsIgnorePartialResults() { return groupsIgnorePartialResults; } public void setGroupsIgnorePartialResults(Boolean groupsIgnorePartialResults) { this.groupsIgnorePartialResults = groupsIgnorePartialResults; } public String getTlsConfiguration() { return tlsConfiguration; } public void setTlsConfiguration(String tlsConfiguration) { if (tlsConfiguration == null) { tlsConfiguration = LDAP_TLS_NONE; } switch (tlsConfiguration) { case LDAP_TLS_NONE: case LDAP_TLS_SIMPLE: case LDAP_TLS_EXTERNAL: this.tlsConfiguration = tlsConfiguration; break; default: throw new IllegalArgumentException(tlsConfiguration); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; LdapIdentityProviderDefinition that = (LdapIdentityProviderDefinition) o; if (maxGroupSearchDepth != that.maxGroupSearchDepth) return false; if (ldapProfileFile != null ? !ldapProfileFile.equals(that.ldapProfileFile) : that.ldapProfileFile != null) return false; if (baseUrl != null ? !baseUrl.equals(that.baseUrl) : that.baseUrl != null) return false; if (referral != null ? !referral.equals(that.referral) : that.referral != null) return false; if (userDNPattern != null ? !userDNPattern.equals(that.userDNPattern) : that.userDNPattern != null) return false; if (userDNPatternDelimiter != null ? !userDNPatternDelimiter.equals(that.userDNPatternDelimiter) : that.userDNPatternDelimiter != null) return false; if (bindUserDn != null ? !bindUserDn.equals(that.bindUserDn) : that.bindUserDn != null) return false; if (bindPassword != null ? !bindPassword.equals(that.bindPassword) : that.bindPassword != null) return false; if (userSearchBase != null ? !userSearchBase.equals(that.userSearchBase) : that.userSearchBase != null) return false; if (userSearchFilter != null ? !userSearchFilter.equals(that.userSearchFilter) : that.userSearchFilter != null) return false; if (passwordAttributeName != null ? !passwordAttributeName.equals(that.passwordAttributeName) : that.passwordAttributeName != null) return false; if (passwordEncoder != null ? !passwordEncoder.equals(that.passwordEncoder) : that.passwordEncoder != null) return false; if (localPasswordCompare != null ? !localPasswordCompare.equals(that.localPasswordCompare) : that.localPasswordCompare != null) return false; if (mailAttributeName != null ? !mailAttributeName.equals(that.mailAttributeName) : that.mailAttributeName != null) return false; if (mailSubstitute != null ? !mailSubstitute.equals(that.mailSubstitute) : that.mailSubstitute != null) return false; if (mailSubstituteOverridesLdap != null ? !mailSubstituteOverridesLdap.equals(that.mailSubstituteOverridesLdap) : that.mailSubstituteOverridesLdap != null) return false; if (ldapGroupFile != null ? !ldapGroupFile.equals(that.ldapGroupFile) : that.ldapGroupFile != null) return false; if (groupSearchBase != null ? !groupSearchBase.equals(that.groupSearchBase) : that.groupSearchBase != null) return false; if (groupSearchFilter != null ? !groupSearchFilter.equals(that.groupSearchFilter) : that.groupSearchFilter != null) return false; if (groupsIgnorePartialResults != null ? !groupsIgnorePartialResults.equals(that.groupsIgnorePartialResults) : that.groupsIgnorePartialResults != null) return false; if (autoAddGroups != null ? !autoAddGroups.equals(that.autoAddGroups) : that.autoAddGroups != null) return false; if (groupSearchSubTree != null ? !groupSearchSubTree.equals(that.groupSearchSubTree) : that.groupSearchSubTree != null) return false; return !(groupRoleAttribute != null ? !groupRoleAttribute.equals(that.groupRoleAttribute) : that.groupRoleAttribute != null); } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (baseUrl != null ? baseUrl.hashCode() : 0); return result; } public static class LdapConfigEnvironment extends AbstractEnvironment { public LdapConfigEnvironment(MapPropertySource source) { getPropertySources().addFirst(source); } } }