mx.edu.um.mateo.general.utils.SpringSecurityUtils.java Source code

Java tutorial

Introduction

Here is the source code for mx.edu.um.mateo.general.utils.SpringSecurityUtils.java

Source

/* Copyright 2006-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package mx.edu.um.mateo.general.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import mx.edu.um.mateo.general.model.Usuario;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter;
import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * Helper methods.
 * 
 * @author <a href='mailto:burt@burtbeckwith.com'>Burt Beckwith</a>
 */
@SuppressWarnings("deprecation")
@Component
public class SpringSecurityUtils {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private RoleHierarchy roleHierarchy;
    /**
     * Default value for the name of the Ajax header.
     */
    public static final String AJAX_HEADER = "X-Requested-With";
    /**
     * Used to ensure that all authenticated users have at least one granted
     * authority to work around Spring Security code that assumes at least one.
     * By granting this non-authority, the user can't do anything but gets past
     * the somewhat arbitrary restrictions.
     */
    public static final String NO_ROLE = "ROLE_NO_ROLES";

    public SpringSecurityUtils() {
    }

    /**
     * Extract the role names from authorities.
     * 
     * @param authorities
     *            the authorities (a collection or array of
     *            {@link GrantedAuthority}).
     * @return the names
     */
    @SuppressWarnings("unchecked")
    public static Set<String> authoritiesToRoles(final Object authorities) {
        Set<String> roles = new HashSet<>();
        for (GrantedAuthority authority : (Collection<GrantedAuthority>) authorities) {
            String authorityName = authority.getAuthority();
            if (null == authorityName) {
                throw new IllegalArgumentException(
                        "Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process "
                                + authority);
            }
            roles.add(authorityName);
        }

        return roles;
    }

    /**
     * Get the current user's authorities.
     * 
     * @return a list of authorities (empty if not authenticated).
     */
    public static Collection<GrantedAuthority> getPrincipalAuthorities() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return Collections.emptyList();
        }

        @SuppressWarnings("unchecked")
        Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) authentication.getAuthorities();
        if (authorities == null) {
            return Collections.emptyList();
        }

        // remove the fake role if it's there
        Collection<GrantedAuthority> copy = new ArrayList<>(authorities);
        for (Iterator<GrantedAuthority> iter = copy.iterator(); iter.hasNext();) {
            if (iter.next().getAuthority().equals(NO_ROLE)) {
                iter.remove();
            }
        }

        return copy;
    }

    /**
     * Split the role names and create {@link GrantedAuthority}s for each.
     * 
     * @param roleNames
     *            comma-delimited role names
     * @return authorities (possibly empty)
     */
    public static List<GrantedAuthority> parseAuthoritiesString(final String roleNames) {
        List<GrantedAuthority> requiredAuthorities = new ArrayList<>();
        for (String auth : StringUtils.commaDelimitedListToStringArray(roleNames)) {
            auth = auth.trim();
            if (auth.length() > 0) {
                requiredAuthorities.add(new GrantedAuthorityImpl(auth));
            }
        }

        return requiredAuthorities;
    }

    /**
     * Find authorities in <code>granted</code> that are also in
     * <code>required</code>.
     * 
     * @param granted
     *            the granted authorities (a collection or array of
     *            {@link SpringSecurityUtils}).
     * @param required
     *            the required authorities (a collection or array of
     *            {@link SpringSecurityUtils}).
     * @return the authority names
     */
    public static Set<String> retainAll(final Object granted, final Object required) {
        Set<String> grantedRoles = authoritiesToRoles(granted);
        Set<String> requiredRoles = authoritiesToRoles(required);
        grantedRoles.retainAll(requiredRoles);
        return grantedRoles;
    }

    /**
     * Check if the current user has all of the specified roles.
     * 
     * @param roles
     *            a comma-delimited list of role names
     * @return <code>true</code> if the user is authenticated and has all the
     *         roles
     */
    public boolean ifAllGranted(final String roles) {
        Collection<GrantedAuthority> inferred = findInferredAuthorities(getPrincipalAuthorities());
        return inferred.containsAll(parseAuthoritiesString(roles));
    }

    /**
     * Check if the current user has none of the specified roles.
     * 
     * @param roles
     *            a comma-delimited list of role names
     * @return <code>true</code> if the user is authenticated and has none the
     *         roles
     */
    public boolean ifNotGranted(final String roles) {
        Collection<GrantedAuthority> inferred = findInferredAuthorities(getPrincipalAuthorities());
        Set<String> grantedCopy = retainAll(inferred, parseAuthoritiesString(roles));
        return grantedCopy.isEmpty();
    }

    /**
     * Check if the current user has any of the specified roles.
     * 
     * @param roles
     *            a comma-delimited list of role names
     * @return <code>true</code> if the user is authenticated and has any the
     *         roles
     */
    public boolean ifAnyGranted(final String roles) {
        Collection<GrantedAuthority> inferred = findInferredAuthorities(getPrincipalAuthorities());
        Set<String> grantedCopy = retainAll(inferred, parseAuthoritiesString(roles));
        return !grantedCopy.isEmpty();
    }

    /**
     * Check if the current user is switched to another user.
     * 
     * @return <code>true</code> if logged in and switched
     */
    public boolean isSwitched() {
        return ifAllGranted(SwitchUserFilter.ROLE_PREVIOUS_ADMINISTRATOR);
    }

    /**
     * Get the username of the original user before switching to another.
     * 
     * @return the original login name
     */
    public String getSwitchedUserOriginalUsername() {
        if (isSwitched()) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            for (GrantedAuthority auth : authentication.getAuthorities()) {
                if (auth instanceof SwitchUserGrantedAuthority) {
                    return ((SwitchUserGrantedAuthority) auth).getSource().getName();
                }
            }
        }
        return null;
    }

    /**
     * Rebuild an Authentication for the given username and register it in the
     * security context. Typically used after updating a user's authorities or
     * other auth-cached info.
     * <p/>
     * Also removes the user from the user cache to force a refresh at next
     * login.
     * 
     * @param username
     *            the user's login name
     * @param password
     *            optional
     */
    public void reauthenticate(final String username, final String password) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(userDetails,
                password == null ? userDetails.getPassword() : password, userDetails.getAuthorities()));
    }

    private Collection<GrantedAuthority> findInferredAuthorities(final Collection<GrantedAuthority> granted) {
        @SuppressWarnings("unchecked")
        Collection<GrantedAuthority> reachable = (Collection<GrantedAuthority>) roleHierarchy
                .getReachableGrantedAuthorities(granted);
        if (reachable == null) {
            return Collections.emptyList();
        }
        return reachable;
    }

    public Usuario obtieneUsuario() {
        Usuario usuario = (Usuario) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return usuario;
    }
}