it.geosolutions.geostore.services.rest.security.GeoStoreLdapAuthoritiesPopulator.java Source code

Java tutorial

Introduction

Here is the source code for it.geosolutions.geostore.services.rest.security.GeoStoreLdapAuthoritiesPopulator.java

Source

/* ====================================================================
 *
 * Copyright (C) 2014 GeoSolutions S.A.S.
 * http://www.geo-solutions.it
 *
 * GPLv3 + Classpath exception
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.
 *
 * ====================================================================
 *
 * This software consists of voluntary contributions made by developers
 * of GeoSolutions.  For more information on GeoSolutions, please see
 * <http://www.geo-solutions.it/>.
 *
 */
package it.geosolutions.geostore.services.rest.security;

import it.geosolutions.geostore.core.security.GrantedAuthoritiesMapper;

import java.util.HashSet;
import java.util.Set;

import javax.naming.directory.SearchControls;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.core.ContextSource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
import org.springframework.util.Assert;

/**
 * @author alessio.fabiani
 *
 */
public class GeoStoreLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator
        implements GroupsRolesService {

    private static final Log logger = LogFactory.getLog(GeoStoreLdapAuthoritiesPopulator.class);

    /**
      * Template that will be used for searching
      */
    private final SpringSecurityLdapTemplate ldapTemplate;

    /**
     * Controls used to determine whether group searches should be performed over the full sub-tree from the
     * base DN. Modified by searchSubTree property
     */
    private final SearchControls searchControls = new SearchControls();

    /**
     * The ID of the attribute which contains the role name for a group
     */
    private String groupRoleAttribute = "cn";

    /**
     * The base DN from which the search for group membership should be performed
     */
    private String groupSearchBase;
    private String roleSearchBase;

    /**
     * The pattern to be used for the user search. {0} is the user's DN
     */
    private String groupSearchFilter = "(member={0})";
    private String roleSearchFilter = "(member={0})";

    private String allGroupsSearchFilter = "(objectClass=group)";
    private String allRolesSearchFilter = "(objectClass=group)";
    /**
     * The role prefix that will be prepended to each role name
     */
    private String rolePrefix = "ROLE_";
    /**
     * Should we convert the role name to uppercase
     */
    private boolean convertToUpperCase = true;

    private GrantedAuthoritiesMapper authoritiesMapper = null;

    /**
     * @param contextSource
     * @param groupSearchBase
     */
    public GeoStoreLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase,
            String roleSearchBase) {
        super(contextSource, groupSearchBase);

        Assert.notNull(contextSource, "contextSource must not be null");
        ldapTemplate = new SpringSecurityLdapTemplate(contextSource);
        ldapTemplate.setSearchControls(searchControls);

        this.groupSearchBase = groupSearchBase;

        if (groupSearchBase == null) {
            logger.info("groupSearchBase is null. No group search will be performed.");
        } else if (groupSearchBase.length() == 0) {
            logger.info("groupSearchBase is empty. Searches will be performed from the context source base");
        }

        this.roleSearchBase = roleSearchBase;

        if (roleSearchBase == null) {
            logger.info("roleSearchBase is null. No group search will be performed.");
        } else if (roleSearchBase.length() == 0) {
            logger.info("roleSearchBase is empty. Searches will be performed from the context source base");
        }
    }

    public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {
        this.authoritiesMapper = authoritiesMapper;
    }

    @Override
    public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
        return getGroupsOrRoles(userDn, username, true, true);
    }

    private Set<GrantedAuthority> getGroupsOrRoles(String userDn, String username, boolean groups, boolean roles) {
        if (roleSearchBase == null && groupSearchBase == null) {
            return new HashSet<GrantedAuthority>();
        }

        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        String[] searchParams = username == null ? new String[] {} : new String[] { userDn, username };
        if (roles) {
            // Searching for ROLES
            if (logger.isDebugEnabled()) {
                logger.debug("Searching for roles for user '" + username + "', DN = " + "'" + userDn
                        + "', with filter " + roleSearchFilter + " in search base '" + roleSearchBase + "'");
            }

            String[] rolesRoots = roleSearchBase.split(",");
            String filter = username == null ? allRolesSearchFilter : roleSearchFilter;

            for (String rolesRoot : rolesRoots) {
                addAuthorities(searchParams, authorities, rolesRoot, filter, rolePrefix);
            }
        }

        if (groups) {
            // Searching for Groups
            if (logger.isDebugEnabled()) {
                logger.debug("Searching for groups for user '" + username + "', DN = " + "'" + userDn
                        + "', with filter " + groupSearchFilter + " in search base '" + groupSearchBase + "'");
            }
            String[] groupsRoots = groupSearchBase.split(",");
            String filter = username == null ? allGroupsSearchFilter : groupSearchFilter;
            for (String groupsRoot : groupsRoots) {
                addAuthorities(searchParams, authorities, groupsRoot, filter, null);
            }
        }

        if (authoritiesMapper != null) {
            return new HashSet<GrantedAuthority>(authoritiesMapper.mapAuthorities(authorities));
        }
        return authorities;
    }

    public Set<GrantedAuthority> getAllGroups() {
        return getGroupsOrRoles(null, null, true, false);
    }

    public Set<GrantedAuthority> getAllRoles() {
        return getGroupsOrRoles(null, null, false, true);
    }

    private void addAuthorities(String[] params, Set<GrantedAuthority> authorities, String root, String filter,
            String authorityPrefix) {
        Set<String> ldapAuthorities = ldapTemplate.searchForSingleAttributeValues(root, filter, params,
                groupRoleAttribute);

        if (logger.isDebugEnabled()) {
            logger.debug("Authorities from search: " + ldapAuthorities);
        }
        for (String authority : ldapAuthorities) {

            addAuthority(authorities, authorityPrefix, authority);
        }
    }

    private void addAuthority(Set<GrantedAuthority> authorities, String authorityPrefix, String authority) {
        if (convertToUpperCase) {
            authority = authority.toUpperCase();
        }

        String prefix = (authorityPrefix != null && !authority.startsWith(authorityPrefix) ? authorityPrefix : "");
        authorities.add(new GrantedAuthorityImpl(prefix + authority));
    }

    @Override
    public void setConvertToUpperCase(boolean convertToUpperCase) {
        super.setConvertToUpperCase(convertToUpperCase);
        this.convertToUpperCase = convertToUpperCase;
    }

    @Override
    public void setGroupRoleAttribute(String groupRoleAttribute) {
        super.setGroupRoleAttribute(groupRoleAttribute);
        this.groupRoleAttribute = groupRoleAttribute;
    }

    @Override
    public void setGroupSearchFilter(String groupSearchFilter) {
        super.setGroupSearchFilter(groupSearchFilter);
        this.groupSearchFilter = groupSearchFilter;
    }

    public void setRoleSearchFilter(String roleSearchFilter) {
        this.roleSearchFilter = roleSearchFilter;
    }

    @Override
    public void setRolePrefix(String rolePrefix) {
        super.setRolePrefix(rolePrefix);
        this.rolePrefix = rolePrefix;
    }

}