Search in sources :

Example 1 with AbstractContextMapper

use of org.springframework.ldap.core.support.AbstractContextMapper in project coprhd-controller by CoprHD.

the class ImmutableAuthenticationProviders method checkDirectoryType.

/**
 * Check directory type/vendor, supported LDAP versions,
 * and make sure configured mode matches with AD/LDAP server type
 *
 * @param template the ldap template to use
 * @param rootDSE the RootDSE object
 * @param param the param structure containing the parameters to validate
 * @param errorString output parameter to store error string
 * @return true if validation succeeded. false otherwise
 */
@SuppressWarnings("rawtypes")
private static boolean checkDirectoryType(LdapTemplate template, RootDSE rootDSE, final AuthnProviderParamsToValidate param, StringBuilder errorString) {
    // check LDAP version
    boolean ldapVersionPassed = false;
    if (rootDSE.getSupportedLDAPVersion() != null) {
        for (int i = 0; i < rootDSE.getSupportedLDAPVersion().length; i++) {
            if (rootDSE.getSupportedLDAPVersion()[i] >= LDAP_VERSION_LEVEL) {
                ldapVersionPassed = true;
                break;
            }
        }
        if (!ldapVersionPassed) {
            String errorMsg = MessageFormat.format("Supported LDAP version is insufficient at server {0}: must be at least {1}.", param.getUrls().toString(), LDAP_VERSION_LEVEL);
            errorString.append(errorMsg);
            _log.error(errorMsg);
            return false;
        }
    } else {
        _log.warn("Failed to get supported LDAP versions at server {}", param.getUrls().toString());
    }
    String serverType = null;
    // check active directory
    String rootDomainNamingContext = rootDSE.getRootDomainNamingContext();
    if (rootDomainNamingContext == null || rootDomainNamingContext.equals("")) {
        serverType = LDAP_SERVER;
        if (!param.getMode().equals("ldap")) {
            String errorMsg = MessageFormat.format("Directory server type LDAP doesn't match with specified mode {1} at server {0}.", param.getUrls().toString(), param.getMode());
            errorString.append(errorMsg);
            _log.error(errorMsg);
            return false;
        }
        serverType = OpenLDAPVersionChecker.getOpenLDAPVersion(rootDSE);
        if (serverType == null) {
            serverType = LDAP_SERVER;
        }
        _log.info("Server type: {} at {}", serverType, param.getUrls().toString());
    } else {
        serverType = MICROSOFT_ACTIVE_DIRECTORY;
        if (!param.getMode().equals("ad")) {
            // using AD as LDAP server only will not take advantage of AD specific features, but it is allowed
            String errorMsg = MessageFormat.format("Directory server type Active Directory doesn't match with specified mode {1} at server {0}.", param.getUrls().toString(), param.getMode());
            _log.warn(errorMsg);
        }
        // retrieve the rootDSE's schemaNamingContext operational attribute
        String schemaDN = rootDSE.getSchemaNamingContext();
        if (schemaDN == null || schemaDN.equals("")) {
            String errorMsg = MessageFormat.format("Could not find Schema Naming Context for server {0}", param.getUrls().toString());
            errorString.append(errorMsg);
            _log.error(errorMsg);
            return false;
        } else {
            _log.debug("Found Schema DN: {} for server {}", schemaDN, param.getUrls().toString());
        }
        // check and record objectVersion, windows server type
        try {
            List list = template.search(schemaDN, "(objectclass=*)", SearchControls.OBJECT_SCOPE, new AbstractContextMapper() {

                @Override
                protected Object doMapFromContext(DirContextOperations ctx) {
                    return ctx.getStringAttribute(OBJECT_VERSION);
                }
            });
            if (CollectionUtils.isEmpty(list)) {
                String errorMsg = MessageFormat.format("The attribute {0} could not be found in AD schema at server {1}.", OBJECT_VERSION, param.getUrls().toString());
                errorString.append(errorMsg);
                _log.error(errorMsg);
                return false;
            }
            String objectVersion = (String) list.get(0);
            String windowsServer = ActiveDirectoryVersionMap.getActiveDirectoryVersion(objectVersion);
            String infoMsg = MessageFormat.format("Active Directory server information {0} - server type: {1}, objectVersion: {2}, Microsoft Windows Server version: {3}", param.getUrls().toString(), serverType, objectVersion, windowsServer);
            _log.info(infoMsg);
            return true;
        } catch (CommunicationException e) {
            String errorMsg = MessageFormat.format("Connection to Active Directory server {0} failed during query of schema DN ({1})'s objectVersion attribute. LDAP error: {2}", param.getUrls().toString(), schemaDN, stripNonPrintableCharacters(e.getMessage()));
            errorString.append(errorMsg);
            _log.error(errorMsg);
            return false;
        } catch (Exception e) {
            String errorMsg = MessageFormat.format("Query {0} against server {1} failed because of LDAP error: {2}", OBJECT_VERSION, param.getUrls().toString(), stripNonPrintableCharacters(e.getMessage()));
            errorString.append(errorMsg);
            _log.error(errorMsg);
            return false;
        }
    }
    return true;
}
Also used : AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) DirContextOperations(org.springframework.ldap.core.DirContextOperations) CommunicationException(org.springframework.ldap.CommunicationException) GroupWhiteList(com.emc.storageos.auth.ldap.GroupWhiteList) ArrayList(java.util.ArrayList) List(java.util.List) AuthenticationException(org.springframework.ldap.AuthenticationException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) CommunicationException(org.springframework.ldap.CommunicationException) SecurityException(com.emc.storageos.security.exceptions.SecurityException) PartialResultException(org.springframework.ldap.PartialResultException) NameNotFoundException(org.springframework.ldap.NameNotFoundException)

Example 2 with AbstractContextMapper

use of org.springframework.ldap.core.support.AbstractContextMapper in project coprhd-controller by CoprHD.

the class ImmutableAuthenticationProviders method checkGroupAttribute.

/**
 * Queries the AD schema to check that the group attribute exists
 *
 * @param template the ldap template to use
 * @param rootDSE the RootDSE object
 * @param param the param structure containing the parameters to validate
 * @param errorString output parameter to store error string
 * @return true if validation succeeded. false otherwise
 */
@SuppressWarnings("rawtypes")
private static boolean checkGroupAttribute(LdapTemplate template, final RootDSE rootDSE, final AuthnProviderParamsToValidate param, StringBuilder errorString) {
    try {
        // retrieve the rootDSE's schemaNamingContext operational attribute
        String schemaDN = rootDSE.getSchemaNamingContext();
        // query for the attribute
        List list = template.search(schemaDN, LdapFilterUtil.getAttributeFilterWithValues(param.getGroupAttr()), SearchControls.ONELEVEL_SCOPE, new AbstractContextMapper() {

            @Override
            protected Object doMapFromContext(DirContextOperations ctx) {
                return ctx.getStringAttribute("cn");
            }
        });
        if (CollectionUtils.isEmpty(list)) {
            errorString.append(MessageFormat.format("The group attribute {0} could not be found in AD schema at server {1}.", param.getGroupAttr(), param.getUrls().toString()));
            return false;
        } else {
            _log.debug("Found attribute: {} {}", list.get(0), param.getGroupAttr());
        }
        return true;
    } catch (CommunicationException e) {
        errorString.append(MessageFormat.format("Connection to LDAP server {0} failed during search for group attribute {1}. LDAP error: {2}", param.getUrls().toString(), param.getGroupAttr(), stripNonPrintableCharacters(e.getMessage())));
        return false;
    } catch (Exception e) {
        errorString.append(MessageFormat.format("Validation of group attribute {0} against server {1} failed because of LDAP error: {2}", param.getGroupAttr(), param.getUrls().toString(), stripNonPrintableCharacters(e.getMessage())));
        return false;
    }
}
Also used : AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) DirContextOperations(org.springframework.ldap.core.DirContextOperations) CommunicationException(org.springframework.ldap.CommunicationException) GroupWhiteList(com.emc.storageos.auth.ldap.GroupWhiteList) ArrayList(java.util.ArrayList) List(java.util.List) AuthenticationException(org.springframework.ldap.AuthenticationException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) CommunicationException(org.springframework.ldap.CommunicationException) SecurityException(com.emc.storageos.security.exceptions.SecurityException) PartialResultException(org.springframework.ldap.PartialResultException) NameNotFoundException(org.springframework.ldap.NameNotFoundException)

Example 3 with AbstractContextMapper

use of org.springframework.ldap.core.support.AbstractContextMapper in project cxf by apache.

the class LdapUtils method getDnOfEntry.

public static Name getDnOfEntry(LdapTemplate ldapTemplate, String baseDN, String objectClass, String filterAttributeName, String filterAttributeValue) {
    ContextMapper<Name> mapper = new AbstractContextMapper<Name>() {

        public Name doMapFromContext(DirContextOperations ctx) {
            return ctx.getDn();
        }
    };
    AndFilter filter = new AndFilter();
    filter.and(new EqualsFilter("objectclass", objectClass)).and(new EqualsFilter(filterAttributeName, filterAttributeValue));
    List<Name> result = ldapTemplate.search((baseDN == null) ? "" : baseDN, filter.toString(), SearchControls.SUBTREE_SCOPE, mapper);
    if (result != null && !result.isEmpty()) {
        // not only the first one....
        return result.get(0);
    }
    return null;
}
Also used : AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) AndFilter(org.springframework.ldap.filter.AndFilter) DirContextOperations(org.springframework.ldap.core.DirContextOperations) EqualsFilter(org.springframework.ldap.filter.EqualsFilter) Name(javax.naming.Name)

Example 4 with AbstractContextMapper

use of org.springframework.ldap.core.support.AbstractContextMapper in project nifi-registry by apache.

the class LdapUserGroupProvider method load.

/**
 * Reloads the tenants.
 */
private void load(final ContextSource contextSource) {
    // create the ldapTemplate based on the context source. use a single source context to use the same connection
    // to support paging when configured
    final SingleContextSource singleContextSource = new SingleContextSource(contextSource.getReadOnlyContext());
    final LdapTemplate ldapTemplate = new LdapTemplate(singleContextSource);
    try {
        final List<User> userList = new ArrayList<>();
        final List<Group> groupList = new ArrayList<>();
        // group dn -> user identifiers lookup
        final Map<String, Set<String>> groupToUserIdentifierMappings = new HashMap<>();
        // user dn -> user lookup
        final Map<String, User> userLookup = new HashMap<>();
        if (performUserSearch) {
            // search controls
            final SearchControls userControls = new SearchControls();
            userControls.setSearchScope(userSearchScope.ordinal());
            // consider paging support for users
            final DirContextProcessor userProcessor;
            if (pageSize == null) {
                userProcessor = new NullDirContextProcessor();
            } else {
                userProcessor = new PagedResultsDirContextProcessor(pageSize);
            }
            // looking for objects matching the user object class
            final AndFilter userFilter = new AndFilter();
            userFilter.and(new EqualsFilter("objectClass", userObjectClass));
            // if a filter has been provided by the user, we add it to the filter
            if (StringUtils.isNotBlank(userSearchFilter)) {
                userFilter.and(new HardcodedFilter(userSearchFilter));
            }
            do {
                userList.addAll(ldapTemplate.search(userSearchBase, userFilter.encode(), userControls, new AbstractContextMapper<User>() {

                    @Override
                    protected User doMapFromContext(DirContextOperations ctx) {
                        // get the user identity
                        final String identity = getUserIdentity(ctx);
                        // build the user
                        final User user = new User.Builder().identifierGenerateFromSeed(identity).identity(identity).build();
                        // store the user for group member later
                        userLookup.put(getReferencedUserValue(ctx), user);
                        if (StringUtils.isNotBlank(userGroupNameAttribute)) {
                            final Attribute attributeGroups = ctx.getAttributes().get(userGroupNameAttribute);
                            if (attributeGroups == null) {
                                logger.warn("User group name attribute [" + userGroupNameAttribute + "] does not exist. Ignoring group membership.");
                            } else {
                                try {
                                    final NamingEnumeration<String> groupValues = (NamingEnumeration<String>) attributeGroups.getAll();
                                    while (groupValues.hasMoreElements()) {
                                        // store the group -> user identifier mapping
                                        groupToUserIdentifierMappings.computeIfAbsent(groupValues.next(), g -> new HashSet<>()).add(user.getIdentifier());
                                    }
                                } catch (NamingException e) {
                                    throw new AuthorizationAccessException("Error while retrieving user group name attribute [" + userIdentityAttribute + "].");
                                }
                            }
                        }
                        return user;
                    }
                }, userProcessor));
            } while (hasMorePages(userProcessor));
        }
        if (performGroupSearch) {
            final SearchControls groupControls = new SearchControls();
            groupControls.setSearchScope(groupSearchScope.ordinal());
            // consider paging support for groups
            final DirContextProcessor groupProcessor;
            if (pageSize == null) {
                groupProcessor = new NullDirContextProcessor();
            } else {
                groupProcessor = new PagedResultsDirContextProcessor(pageSize);
            }
            // looking for objects matching the group object class
            AndFilter groupFilter = new AndFilter();
            groupFilter.and(new EqualsFilter("objectClass", groupObjectClass));
            // if a filter has been provided by the user, we add it to the filter
            if (StringUtils.isNotBlank(groupSearchFilter)) {
                groupFilter.and(new HardcodedFilter(groupSearchFilter));
            }
            do {
                groupList.addAll(ldapTemplate.search(groupSearchBase, groupFilter.encode(), groupControls, new AbstractContextMapper<Group>() {

                    @Override
                    protected Group doMapFromContext(DirContextOperations ctx) {
                        final String dn = ctx.getDn().toString();
                        // get the group identity
                        final String name = getGroupName(ctx);
                        // get the value of this group that may associate it to users
                        final String referencedGroupValue = getReferencedGroupValue(ctx);
                        if (!StringUtils.isBlank(groupMemberAttribute)) {
                            Attribute attributeUsers = ctx.getAttributes().get(groupMemberAttribute);
                            if (attributeUsers == null) {
                                logger.warn("Group member attribute [" + groupMemberAttribute + "] does not exist. Ignoring group membership.");
                            } else {
                                try {
                                    final NamingEnumeration<String> userValues = (NamingEnumeration<String>) attributeUsers.getAll();
                                    while (userValues.hasMoreElements()) {
                                        final String userValue = userValues.next();
                                        if (performUserSearch) {
                                            // find the user by it's referenced attribute and add the identifier to this group
                                            final User user = userLookup.get(userValue);
                                            // ensure the user is known
                                            if (user != null) {
                                                groupToUserIdentifierMappings.computeIfAbsent(referencedGroupValue, g -> new HashSet<>()).add(user.getIdentifier());
                                            } else {
                                                logger.warn(String.format("%s contains member %s but that user was not found while searching users. Ignoring group membership.", name, userValue));
                                            }
                                        } else {
                                            // since performUserSearch is false, then the referenced group attribute must be blank... the user value must be the dn
                                            final String userDn = userValue;
                                            final String userIdentity;
                                            if (useDnForUserIdentity) {
                                                // use the user value to avoid the unnecessary look up
                                                userIdentity = userDn;
                                            } else {
                                                // lookup the user to extract the user identity
                                                userIdentity = getUserIdentity((DirContextAdapter) ldapTemplate.lookup(userDn));
                                            }
                                            // build the user
                                            final User user = new User.Builder().identifierGenerateFromSeed(userIdentity).identity(userIdentity).build();
                                            // add this user
                                            userList.add(user);
                                            groupToUserIdentifierMappings.computeIfAbsent(referencedGroupValue, g -> new HashSet<>()).add(user.getIdentifier());
                                        }
                                    }
                                } catch (NamingException e) {
                                    throw new AuthorizationAccessException("Error while retrieving group name attribute [" + groupNameAttribute + "].");
                                }
                            }
                        }
                        // build this group
                        final Group.Builder groupBuilder = new Group.Builder().identifierGenerateFromSeed(name).name(name);
                        // add all users that were associated with this referenced group attribute
                        if (groupToUserIdentifierMappings.containsKey(referencedGroupValue)) {
                            groupToUserIdentifierMappings.remove(referencedGroupValue).forEach(userIdentifier -> groupBuilder.addUser(userIdentifier));
                        }
                        return groupBuilder.build();
                    }
                }, groupProcessor));
            } while (hasMorePages(groupProcessor));
            // any remaining groupDn's were referenced by a user but not found while searching groups
            groupToUserIdentifierMappings.forEach((referencedGroupValue, userIdentifiers) -> {
                logger.warn(String.format("[%s] are members of %s but that group was not found while searching users. Ignoring group membership.", StringUtils.join(userIdentifiers, ", "), referencedGroupValue));
            });
        } else {
            // since performGroupSearch is false, then the referenced user attribute must be blank... the group value must be the dn
            // groups are not being searched so lookup any groups identified while searching users
            groupToUserIdentifierMappings.forEach((groupDn, userIdentifiers) -> {
                final String groupName;
                if (useDnForGroupName) {
                    // use the dn to avoid the unnecessary look up
                    groupName = groupDn;
                } else {
                    groupName = getGroupName((DirContextAdapter) ldapTemplate.lookup(groupDn));
                }
                // define the group
                final Group.Builder groupBuilder = new Group.Builder().identifierGenerateFromSeed(groupName).name(groupName);
                // add each user
                userIdentifiers.forEach(userIdentifier -> groupBuilder.addUser(userIdentifier));
                // build the group
                groupList.add(groupBuilder.build());
            });
        }
        // record the updated tenants
        tenants.set(new TenantHolder(new HashSet<>(userList), new HashSet<>(groupList)));
    } finally {
        singleContextSource.destroy();
    }
}
Also used : SSLContext(javax.net.ssl.SSLContext) AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) AndFilter(org.springframework.ldap.filter.AndFilter) ClientAuth(org.apache.nifi.registry.security.util.SslContextFactory.ClientAuth) LoggerFactory(org.slf4j.LoggerFactory) LdapTemplate(org.springframework.ldap.core.LdapTemplate) NamingException(javax.naming.NamingException) KeyStoreException(java.security.KeyStoreException) StringUtils(org.apache.commons.lang3.StringUtils) Attribute(javax.naming.directory.Attribute) Map(java.util.Map) DirContextAdapter(org.springframework.ldap.core.DirContextAdapter) ThreadFactory(java.util.concurrent.ThreadFactory) LdapsSocketFactory(org.apache.nifi.registry.security.ldap.LdapsSocketFactory) LdapContextSource(org.springframework.ldap.core.support.LdapContextSource) AuthorizerContext(org.apache.nifi.registry.security.authorization.annotation.AuthorizerContext) UserGroupProvider(org.apache.nifi.registry.security.authorization.UserGroupProvider) Set(java.util.Set) KeyManagementException(java.security.KeyManagementException) HardcodedFilter(org.springframework.ldap.filter.HardcodedFilter) LdapAuthenticationStrategy(org.apache.nifi.registry.security.ldap.LdapAuthenticationStrategy) SslContextFactory(org.apache.nifi.registry.security.util.SslContextFactory) Executors(java.util.concurrent.Executors) List(java.util.List) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) NamingEnumeration(javax.naming.NamingEnumeration) SingleContextSource(org.springframework.ldap.core.support.SingleContextSource) IdentityMapping(org.apache.nifi.registry.properties.util.IdentityMapping) DirContextOperations(org.springframework.ldap.core.DirContextOperations) PagedResultsDirContextProcessor(org.springframework.ldap.control.PagedResultsDirContextProcessor) ReferralStrategy(org.apache.nifi.registry.security.ldap.ReferralStrategy) NullDirContextProcessor(org.springframework.ldap.core.LdapTemplate.NullDirContextProcessor) DirContextProcessor(org.springframework.ldap.core.DirContextProcessor) IdentityMappingUtil(org.apache.nifi.registry.properties.util.IdentityMappingUtil) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) SearchControls(javax.naming.directory.SearchControls) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Group(org.apache.nifi.registry.security.authorization.Group) SimpleDirContextAuthenticationStrategy(org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy) UserGroupProviderInitializationContext(org.apache.nifi.registry.security.authorization.UserGroupProviderInitializationContext) NiFiRegistryProperties(org.apache.nifi.registry.properties.NiFiRegistryProperties) UserAndGroups(org.apache.nifi.registry.security.authorization.UserAndGroups) UnrecoverableKeyException(java.security.UnrecoverableKeyException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) AbstractTlsDirContextAuthenticationStrategy(org.springframework.ldap.core.support.AbstractTlsDirContextAuthenticationStrategy) SecurityProviderDestructionException(org.apache.nifi.registry.security.exception.SecurityProviderDestructionException) DefaultTlsDirContextAuthenticationStrategy(org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy) Context(javax.naming.Context) AuthorizationAccessException(org.apache.nifi.registry.security.authorization.exception.AuthorizationAccessException) Logger(org.slf4j.Logger) ContextSource(org.springframework.ldap.core.ContextSource) SecurityProviderCreationException(org.apache.nifi.registry.security.exception.SecurityProviderCreationException) User(org.apache.nifi.registry.security.authorization.User) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) TimeUnit(java.util.concurrent.TimeUnit) EqualsFilter(org.springframework.ldap.filter.EqualsFilter) AuthorizerConfigurationContext(org.apache.nifi.registry.security.authorization.AuthorizerConfigurationContext) PropertyValue(org.apache.nifi.registry.util.PropertyValue) Collections(java.util.Collections) FormatUtils(org.apache.nifi.registry.util.FormatUtils) Group(org.apache.nifi.registry.security.authorization.Group) User(org.apache.nifi.registry.security.authorization.User) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) Attribute(javax.naming.directory.Attribute) ArrayList(java.util.ArrayList) NamingEnumeration(javax.naming.NamingEnumeration) PagedResultsDirContextProcessor(org.springframework.ldap.control.PagedResultsDirContextProcessor) NullDirContextProcessor(org.springframework.ldap.core.LdapTemplate.NullDirContextProcessor) DirContextProcessor(org.springframework.ldap.core.DirContextProcessor) PagedResultsDirContextProcessor(org.springframework.ldap.control.PagedResultsDirContextProcessor) LdapTemplate(org.springframework.ldap.core.LdapTemplate) AuthorizationAccessException(org.apache.nifi.registry.security.authorization.exception.AuthorizationAccessException) DirContextAdapter(org.springframework.ldap.core.DirContextAdapter) SearchControls(javax.naming.directory.SearchControls) NamingException(javax.naming.NamingException) EqualsFilter(org.springframework.ldap.filter.EqualsFilter) HashSet(java.util.HashSet) SingleContextSource(org.springframework.ldap.core.support.SingleContextSource) NullDirContextProcessor(org.springframework.ldap.core.LdapTemplate.NullDirContextProcessor) HardcodedFilter(org.springframework.ldap.filter.HardcodedFilter) AndFilter(org.springframework.ldap.filter.AndFilter) AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) DirContextOperations(org.springframework.ldap.core.DirContextOperations)

Example 5 with AbstractContextMapper

use of org.springframework.ldap.core.support.AbstractContextMapper in project nifi by apache.

the class LdapUserGroupProvider method load.

/**
 * Reloads the tenants.
 */
private void load(final ContextSource contextSource) {
    // create the ldapTemplate based on the context source. use a single source context to use the same connection
    // to support paging when configured
    final SingleContextSource singleContextSource = new SingleContextSource(contextSource.getReadOnlyContext());
    final LdapTemplate ldapTemplate = new LdapTemplate(singleContextSource);
    try {
        final List<User> userList = new ArrayList<>();
        final List<Group> groupList = new ArrayList<>();
        // group dn -> user identifiers lookup
        final Map<String, Set<String>> groupToUserIdentifierMappings = new HashMap<>();
        // user dn -> user lookup
        final Map<String, User> userLookup = new HashMap<>();
        if (performUserSearch) {
            // search controls
            final SearchControls userControls = new SearchControls();
            userControls.setSearchScope(userSearchScope.ordinal());
            // consider paging support for users
            final DirContextProcessor userProcessor;
            if (pageSize == null) {
                userProcessor = new NullDirContextProcessor();
            } else {
                userProcessor = new PagedResultsDirContextProcessor(pageSize);
            }
            // looking for objects matching the user object class
            final AndFilter userFilter = new AndFilter();
            userFilter.and(new EqualsFilter("objectClass", userObjectClass));
            // if a filter has been provided by the user, we add it to the filter
            if (StringUtils.isNotBlank(userSearchFilter)) {
                userFilter.and(new HardcodedFilter(userSearchFilter));
            }
            do {
                userList.addAll(ldapTemplate.search(userSearchBase, userFilter.encode(), userControls, new AbstractContextMapper<User>() {

                    @Override
                    protected User doMapFromContext(DirContextOperations ctx) {
                        // get the user identity
                        final String identity = getUserIdentity(ctx);
                        // build the user
                        final User user = new User.Builder().identifierGenerateFromSeed(identity).identity(identity).build();
                        // store the user for group member later
                        userLookup.put(getReferencedUserValue(ctx), user);
                        if (StringUtils.isNotBlank(userGroupNameAttribute)) {
                            final Attribute attributeGroups = ctx.getAttributes().get(userGroupNameAttribute);
                            if (attributeGroups == null) {
                                logger.warn("User group name attribute [" + userGroupNameAttribute + "] does not exist. Ignoring group membership.");
                            } else {
                                try {
                                    final NamingEnumeration<String> groupValues = (NamingEnumeration<String>) attributeGroups.getAll();
                                    while (groupValues.hasMoreElements()) {
                                        // store the group -> user identifier mapping
                                        groupToUserIdentifierMappings.computeIfAbsent(groupValues.next(), g -> new HashSet<>()).add(user.getIdentifier());
                                    }
                                } catch (NamingException e) {
                                    throw new AuthorizationAccessException("Error while retrieving user group name attribute [" + userIdentityAttribute + "].");
                                }
                            }
                        }
                        return user;
                    }
                }, userProcessor));
            } while (hasMorePages(userProcessor));
        }
        if (performGroupSearch) {
            final SearchControls groupControls = new SearchControls();
            groupControls.setSearchScope(groupSearchScope.ordinal());
            // consider paging support for groups
            final DirContextProcessor groupProcessor;
            if (pageSize == null) {
                groupProcessor = new NullDirContextProcessor();
            } else {
                groupProcessor = new PagedResultsDirContextProcessor(pageSize);
            }
            // looking for objects matching the group object class
            AndFilter groupFilter = new AndFilter();
            groupFilter.and(new EqualsFilter("objectClass", groupObjectClass));
            // if a filter has been provided by the user, we add it to the filter
            if (StringUtils.isNotBlank(groupSearchFilter)) {
                groupFilter.and(new HardcodedFilter(groupSearchFilter));
            }
            do {
                groupList.addAll(ldapTemplate.search(groupSearchBase, groupFilter.encode(), groupControls, new AbstractContextMapper<Group>() {

                    @Override
                    protected Group doMapFromContext(DirContextOperations ctx) {
                        final String dn = ctx.getDn().toString();
                        // get the group identity
                        final String name = getGroupName(ctx);
                        // get the value of this group that may associate it to users
                        final String referencedGroupValue = getReferencedGroupValue(ctx);
                        if (!StringUtils.isBlank(groupMemberAttribute)) {
                            Attribute attributeUsers = ctx.getAttributes().get(groupMemberAttribute);
                            if (attributeUsers == null) {
                                logger.warn("Group member attribute [" + groupMemberAttribute + "] does not exist. Ignoring group membership.");
                            } else {
                                try {
                                    final NamingEnumeration<String> userValues = (NamingEnumeration<String>) attributeUsers.getAll();
                                    while (userValues.hasMoreElements()) {
                                        final String userValue = userValues.next();
                                        if (performUserSearch) {
                                            // find the user by it's referenced attribute and add the identifier to this group
                                            final User user = userLookup.get(userValue);
                                            // ensure the user is known
                                            if (user != null) {
                                                groupToUserIdentifierMappings.computeIfAbsent(referencedGroupValue, g -> new HashSet<>()).add(user.getIdentifier());
                                            } else {
                                                logger.warn(String.format("%s contains member %s but that user was not found while searching users. Ignoring group membership.", name, userValue));
                                            }
                                        } else {
                                            // since performUserSearch is false, then the referenced group attribute must be blank... the user value must be the dn
                                            final String userDn = userValue;
                                            final String userIdentity;
                                            if (useDnForUserIdentity) {
                                                // use the user value to avoid the unnecessary look up
                                                userIdentity = userDn;
                                            } else {
                                                // lookup the user to extract the user identity
                                                userIdentity = getUserIdentity((DirContextAdapter) ldapTemplate.lookup(userDn));
                                            }
                                            // build the user
                                            final User user = new User.Builder().identifierGenerateFromSeed(userIdentity).identity(userIdentity).build();
                                            // add this user
                                            userList.add(user);
                                            groupToUserIdentifierMappings.computeIfAbsent(referencedGroupValue, g -> new HashSet<>()).add(user.getIdentifier());
                                        }
                                    }
                                } catch (NamingException e) {
                                    throw new AuthorizationAccessException("Error while retrieving group name attribute [" + groupNameAttribute + "].");
                                }
                            }
                        }
                        // build this group
                        final Group.Builder groupBuilder = new Group.Builder().identifierGenerateFromSeed(name).name(name);
                        // add all users that were associated with this referenced group attribute
                        if (groupToUserIdentifierMappings.containsKey(referencedGroupValue)) {
                            groupToUserIdentifierMappings.remove(referencedGroupValue).forEach(userIdentifier -> groupBuilder.addUser(userIdentifier));
                        }
                        return groupBuilder.build();
                    }
                }, groupProcessor));
            } while (hasMorePages(groupProcessor));
            // any remaining groupDn's were referenced by a user but not found while searching groups
            groupToUserIdentifierMappings.forEach((referencedGroupValue, userIdentifiers) -> {
                logger.warn(String.format("[%s] are members of %s but that group was not found while searching users. Ignoring group membership.", StringUtils.join(userIdentifiers, ", "), referencedGroupValue));
            });
        } else {
            // since performGroupSearch is false, then the referenced user attribute must be blank... the group value must be the dn
            // groups are not being searched so lookup any groups identified while searching users
            groupToUserIdentifierMappings.forEach((groupDn, userIdentifiers) -> {
                final String groupName;
                if (useDnForGroupName) {
                    // use the dn to avoid the unnecessary look up
                    groupName = groupDn;
                } else {
                    groupName = getGroupName((DirContextAdapter) ldapTemplate.lookup(groupDn));
                }
                // define the group
                final Group.Builder groupBuilder = new Group.Builder().identifierGenerateFromSeed(groupName).name(groupName);
                // add each user
                userIdentifiers.forEach(userIdentifier -> groupBuilder.addUser(userIdentifier));
                // build the group
                groupList.add(groupBuilder.build());
            });
        }
        // record the updated tenants
        tenants.set(new TenantHolder(new HashSet<>(userList), new HashSet<>(groupList)));
    } finally {
        singleContextSource.destroy();
    }
}
Also used : SSLContext(javax.net.ssl.SSLContext) AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) AndFilter(org.springframework.ldap.filter.AndFilter) LoggerFactory(org.slf4j.LoggerFactory) LdapTemplate(org.springframework.ldap.core.LdapTemplate) NamingException(javax.naming.NamingException) KeyStoreException(java.security.KeyStoreException) StringUtils(org.apache.commons.lang3.StringUtils) PropertyValue(org.apache.nifi.components.PropertyValue) UserGroupProvider(org.apache.nifi.authorization.UserGroupProvider) Attribute(javax.naming.directory.Attribute) Map(java.util.Map) AuthorizerCreationException(org.apache.nifi.authorization.exception.AuthorizerCreationException) DirContextAdapter(org.springframework.ldap.core.DirContextAdapter) ThreadFactory(java.util.concurrent.ThreadFactory) LdapContextSource(org.springframework.ldap.core.support.LdapContextSource) Set(java.util.Set) AuthorizerConfigurationContext(org.apache.nifi.authorization.AuthorizerConfigurationContext) KeyManagementException(java.security.KeyManagementException) HardcodedFilter(org.springframework.ldap.filter.HardcodedFilter) Executors(java.util.concurrent.Executors) User(org.apache.nifi.authorization.User) UserAndGroups(org.apache.nifi.authorization.UserAndGroups) List(java.util.List) ClientAuth(org.apache.nifi.security.util.SslContextFactory.ClientAuth) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) NamingEnumeration(javax.naming.NamingEnumeration) SingleContextSource(org.springframework.ldap.core.support.SingleContextSource) UserGroupProviderInitializationContext(org.apache.nifi.authorization.UserGroupProviderInitializationContext) DirContextOperations(org.springframework.ldap.core.DirContextOperations) LdapsSocketFactory(org.apache.nifi.ldap.LdapsSocketFactory) PagedResultsDirContextProcessor(org.springframework.ldap.control.PagedResultsDirContextProcessor) NullDirContextProcessor(org.springframework.ldap.core.LdapTemplate.NullDirContextProcessor) DirContextProcessor(org.springframework.ldap.core.DirContextProcessor) HashMap(java.util.HashMap) Group(org.apache.nifi.authorization.Group) AtomicReference(java.util.concurrent.atomic.AtomicReference) SearchControls(javax.naming.directory.SearchControls) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SimpleDirContextAuthenticationStrategy(org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy) AuthorizerContext(org.apache.nifi.authorization.annotation.AuthorizerContext) UnrecoverableKeyException(java.security.UnrecoverableKeyException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) AbstractTlsDirContextAuthenticationStrategy(org.springframework.ldap.core.support.AbstractTlsDirContextAuthenticationStrategy) DefaultTlsDirContextAuthenticationStrategy(org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy) Context(javax.naming.Context) IdentityMapping(org.apache.nifi.authorization.util.IdentityMapping) ProviderDestructionException(org.apache.nifi.authentication.exception.ProviderDestructionException) IdentityMappingUtil(org.apache.nifi.authorization.util.IdentityMappingUtil) Logger(org.slf4j.Logger) ContextSource(org.springframework.ldap.core.ContextSource) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) TimeUnit(java.util.concurrent.TimeUnit) EqualsFilter(org.springframework.ldap.filter.EqualsFilter) ReferralStrategy(org.apache.nifi.ldap.ReferralStrategy) FormatUtils(org.apache.nifi.util.FormatUtils) NiFiProperties(org.apache.nifi.util.NiFiProperties) SslContextFactory(org.apache.nifi.security.util.SslContextFactory) AuthorizationAccessException(org.apache.nifi.authorization.exception.AuthorizationAccessException) LdapAuthenticationStrategy(org.apache.nifi.ldap.LdapAuthenticationStrategy) Collections(java.util.Collections) Group(org.apache.nifi.authorization.Group) User(org.apache.nifi.authorization.User) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) Attribute(javax.naming.directory.Attribute) ArrayList(java.util.ArrayList) NamingEnumeration(javax.naming.NamingEnumeration) PagedResultsDirContextProcessor(org.springframework.ldap.control.PagedResultsDirContextProcessor) NullDirContextProcessor(org.springframework.ldap.core.LdapTemplate.NullDirContextProcessor) DirContextProcessor(org.springframework.ldap.core.DirContextProcessor) PagedResultsDirContextProcessor(org.springframework.ldap.control.PagedResultsDirContextProcessor) LdapTemplate(org.springframework.ldap.core.LdapTemplate) AuthorizationAccessException(org.apache.nifi.authorization.exception.AuthorizationAccessException) DirContextAdapter(org.springframework.ldap.core.DirContextAdapter) SearchControls(javax.naming.directory.SearchControls) NamingException(javax.naming.NamingException) EqualsFilter(org.springframework.ldap.filter.EqualsFilter) HashSet(java.util.HashSet) SingleContextSource(org.springframework.ldap.core.support.SingleContextSource) NullDirContextProcessor(org.springframework.ldap.core.LdapTemplate.NullDirContextProcessor) HardcodedFilter(org.springframework.ldap.filter.HardcodedFilter) AndFilter(org.springframework.ldap.filter.AndFilter) AbstractContextMapper(org.springframework.ldap.core.support.AbstractContextMapper) DirContextOperations(org.springframework.ldap.core.DirContextOperations)

Aggregations

ArrayList (java.util.ArrayList)4 List (java.util.List)4 DirContextOperations (org.springframework.ldap.core.DirContextOperations)4 AbstractContextMapper (org.springframework.ldap.core.support.AbstractContextMapper)4 GroupWhiteList (com.emc.storageos.auth.ldap.GroupWhiteList)2 SecurityException (com.emc.storageos.security.exceptions.SecurityException)2 APIException (com.emc.storageos.svcs.errorhandling.resources.APIException)2 IOException (java.io.IOException)2 KeyManagementException (java.security.KeyManagementException)2 KeyStoreException (java.security.KeyStoreException)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 UnrecoverableKeyException (java.security.UnrecoverableKeyException)2 CertificateException (java.security.cert.CertificateException)2 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 Set (java.util.Set)2 Executors (java.util.concurrent.Executors)2 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)2