mitm.djigzo.web.common.security.Authorizer.java Source code

Java tutorial

Introduction

Here is the source code for mitm.djigzo.web.common.security.Authorizer.java

Source

/*
 * Copyright 2007 Robin Helgelin
 * Copyright 2008 Jonathan Barker
 *
 * 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 mitm.djigzo.web.common.security;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.util.StringUtils;

/**
 * Based on IfRole which is Apache 2 licensed.
 *  
 * Original authors:
 * 
 * @author Jonathan Barker
 * @author Robin Helgelin
 * @author Tapestry Project (doc comments)
 *
 * @author some minor modifications so the code could be reused.
 */
@SuppressWarnings("rawtypes")
public class Authorizer {
    /** 
     * If the logged in user matches this role, then the body of the IfRole component is rendered. If false, the body is
     * omitted.  This is retained for backward compatibility, and corresponds to a single entry in ifAnyGranted
     */
    private String role;

    /**
     * A comma-separated list of roles is supplied to one or more of the
     * following parameters. If none are supplied, the default behavior is to
     * permit access. Behavior should be self-explanatory.
     */
    private String ifAllGranted;

    private String ifAnyGranted;

    private String ifNotGranted;

    private Collection getPrincipalAuthorities() {
        Authentication currentUser = null;
        currentUser = SecurityContextHolder.getContext().getAuthentication();

        if (null == currentUser) {
            return Collections.EMPTY_LIST;
        }

        if ((null == currentUser.getAuthorities()) || (currentUser.getAuthorities().length < 1)) {
            return Collections.EMPTY_LIST;
        }

        Collection granted = Arrays.asList(currentUser.getAuthorities());
        return granted;
    }

    @SuppressWarnings("unchecked")
    private Set authoritiesToRoles(Collection c) {
        Set target = new HashSet();

        for (Iterator iterator = c.iterator(); iterator.hasNext();) {
            GrantedAuthority authority = (GrantedAuthority) iterator.next();

            if (null == authority.getAuthority()) {
                throw new IllegalArgumentException(
                        "Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process "
                                + authority.toString());
            }

            target.add(authority.getAuthority());
        }

        return target;
    }

    @SuppressWarnings("unchecked")
    private Set parseAuthoritiesString(String authorizationsString) {
        final Set requiredAuthorities = new HashSet();
        final String[] authorities = StringUtils.commaDelimitedListToStringArray(authorizationsString);

        for (int i = 0; i < authorities.length; i++) {
            String authority = authorities[i];

            // Remove the role's whitespace characters without depending on JDK 1.4+
            // Includes space, tab, new line, carriage return and form feed.
            String role = StringUtils.replace(authority, " ", "");
            role = StringUtils.replace(role, "\t", "");
            role = StringUtils.replace(role, "\r", "");
            role = StringUtils.replace(role, "\n", "");
            role = StringUtils.replace(role, "\f", "");

            requiredAuthorities.add(new GrantedAuthorityImpl(role));
        }

        return requiredAuthorities;
    }

    /**
     * Find the common authorities between the current authentication's {@link
     * GrantedAuthority} and the ones that have been specified in the tag's
     * ifAny, ifNot or ifAllGranted attributes.
     * 
     * <p>
     * We need to manually iterate over both collections, because the granted
     * authorities might not implement {@link Object#equals(Object)} and
     * {@link Object#hashCode()} in the same way as {@link
     * GrantedAuthorityImpl}, thereby invalidating {@link
     * Collection#retainAll(java.util.Collection)} results.
     * </p>
     * 
     * <p>
     * <strong>CAVEAT</strong>: This method <strong>will not</strong> work if
     * the granted authorities returns a <code>null</code> string as the
     * return value of {@link
     * org.acegisecurity.GrantedAuthority#getAuthority()}.
     * </p>
     * 
     * <p>
     * Reported by rawdave, on Fri Feb 04, 2005 2:11 pm in the Acegi Security
     * System for Spring forums.
     * </p>
     * 
     * @param granted
     *            The authorities granted by the authentication. May be any
     *            implementation of {@link GrantedAuthority} that does
     *            <strong>not</strong> return <code>null</code> from {@link
     *            org.acegisecurity.GrantedAuthority#getAuthority()}.
     * @param required
     *            A {@link Set} of {@link GrantedAuthorityImpl}s that have been
     *            built using ifAny, ifAll or ifNotGranted.
     * 
     * @return A set containing only the common authorities between <var>granted</var>
     *         and <var>required</var>.
     * 
     */
    @SuppressWarnings("unchecked")
    private Set retainAll(final Collection granted, final Set required) {
        Set grantedRoles = authoritiesToRoles(granted);
        Set requiredRoles = authoritiesToRoles(required);
        grantedRoles.retainAll(requiredRoles);

        return rolesToAuthorities(grantedRoles, granted);
    }

    /**
     * @param grantedRoles
     * @param granted
     * @return a Set of Authorities corresponding to the roles in the grantedRoles
     * that are also in the granted Set of Authorities
     */
    @SuppressWarnings("unchecked")
    private Set rolesToAuthorities(Set grantedRoles, Collection granted) {
        Set target = new HashSet();

        for (Iterator iterator = grantedRoles.iterator(); iterator.hasNext();) {
            String role = (String) iterator.next();

            for (Iterator grantedIterator = granted.iterator(); grantedIterator.hasNext();) {
                GrantedAuthority authority = (GrantedAuthority) grantedIterator.next();

                if (authority.getAuthority().equals(role)) {
                    target.add(authority);
                    break;
                }
            }
        }

        return target;
    }

    /**
     * @return false as the default.  Returns true if all non-null role expressions are 
     * satisfied.  Typically, only one will be used, but if more than one are used, then 
     * the conditions are effectively AND'd 
     */
    @SuppressWarnings("unchecked")
    public boolean isAuthorized() {
        if (((null == ifAllGranted) || "".equals(ifAllGranted))
                && ((null == ifAnyGranted) || "".equals(ifAnyGranted)) && ((null == role) || "".equals(role))
                && ((null == ifNotGranted) || "".equals(ifNotGranted))) {
            return false;
        }

        final Collection granted = getPrincipalAuthorities();

        if ((null != role) && !"".equals(role)) {
            Set grantedCopy = retainAll(granted, parseAuthoritiesString(role));

            if (grantedCopy.isEmpty()) {
                return false;
            }
        }

        if ((null != ifNotGranted) && !"".equals(ifNotGranted)) {
            Set grantedCopy = retainAll(granted, parseAuthoritiesString(ifNotGranted));

            if (!grantedCopy.isEmpty()) {
                return false;
            }
        }

        if ((null != ifAllGranted) && !"".equals(ifAllGranted)) {
            if (!granted.containsAll(parseAuthoritiesString(ifAllGranted))) {
                return false;
            }
        }

        if ((null != ifAnyGranted) && !"".equals(ifAnyGranted)) {
            Set grantedCopy = retainAll(granted, parseAuthoritiesString(ifAnyGranted));

            if (grantedCopy.isEmpty()) {
                return false;
            }
        }

        return true;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getIfAllGranted() {
        return ifAllGranted;
    }

    public void setIfAllGranted(String ifAllGranted) {
        this.ifAllGranted = ifAllGranted;
    }

    public String getIfAnyGranted() {
        return ifAnyGranted;
    }

    public void setIfAnyGranted(String ifAnyGranted) {
        this.ifAnyGranted = ifAnyGranted;
    }

    public String getIfNotGranted() {
        return ifNotGranted;
    }

    public void setIfNotGranted(String ifNotGranted) {
        this.ifNotGranted = ifNotGranted;
    }
}