Package org.springframework.security.config.annotation.web.configurers

Source Code of org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer$AuthorizedUrl

/*
* Copyright 2002-2013 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 org.springframework.security.config.annotation.web.configurers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;

import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.security.web.util.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
* Adds URL based authorization based upon SpEL expressions to an application. At least one
* {@link org.springframework.web.bind.annotation.RequestMapping} needs to be mapped to {@link ConfigAttribute}'s for
* this {@link SecurityContextConfigurer} to have meaning.
* <h2>Security Filters</h2>
*
* The following Filters are populated
*
* <ul>
*     <li>{@link org.springframework.security.web.access.intercept.FilterSecurityInterceptor}</li>
* </ul>
*
* <h2>Shared Objects Created</h2>
*
* The following shared objects are populated to allow other {@link org.springframework.security.config.annotation.SecurityConfigurer}'s to customize:
* <ul>
*     <li>{@link org.springframework.security.web.access.intercept.FilterSecurityInterceptor}</li>
* </ul>
*
* <h2>Shared Objects Used</h2>
*
* The following shared objects are used:
*
* <ul>
*     <li>{@link org.springframework.security.config.annotation.web.builders.HttpSecurity#getAuthenticationManager()}</li>
* </ul>
*
* @param <H> the type of {@link HttpSecurityBuilder} that is being configured
*
* @author Rob Winch
* @since 3.2
* @see {@link org.springframework.security.config.annotation.web.builders.HttpSecurity#authorizeUrls()}
*/
public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractInterceptUrlConfigurer<H,ExpressionUrlAuthorizationConfigurer<H>,ExpressionUrlAuthorizationConfigurer<H>.AuthorizedUrl> {
    static final String permitAll = "permitAll";
    private static final String denyAll = "denyAll";
    private static final String anonymous = "anonymous";
    private static final String authenticated = "authenticated";
    private static final String fullyAuthenticated = "fullyAuthenticated";
    private static final String rememberMe = "rememberMe";

    private SecurityExpressionHandler<FilterInvocation> expressionHandler = new DefaultWebSecurityExpressionHandler();

    /**
     * Creates a new instance
     * @see HttpSecurity#authorizeUrls()
     */
    public ExpressionUrlAuthorizationConfigurer() {
    }

    /**
     * Allows customization of the {@link SecurityExpressionHandler} to be used. The default is {@link DefaultWebSecurityExpressionHandler}
     *
     * @param expressionHandler the {@link SecurityExpressionHandler} to be used
     * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization.
     */
    public ExpressionUrlAuthorizationConfigurer<H> expressionHandler(SecurityExpressionHandler<FilterInvocation> expressionHandler) {
        this.expressionHandler = expressionHandler;
        return this;
    }

    @Override
    protected final AuthorizedUrl chainRequestMatchersInternal(List<RequestMatcher> requestMatchers) {
        return new AuthorizedUrl(requestMatchers);
    }

    @Override
    @SuppressWarnings("rawtypes")
    final List<AccessDecisionVoter> getDecisionVoters() {
        List<AccessDecisionVoter> decisionVoters = new ArrayList<AccessDecisionVoter>();
        WebExpressionVoter expressionVoter = new WebExpressionVoter();
        expressionVoter.setExpressionHandler(expressionHandler);
        decisionVoters.add(expressionVoter);
        return decisionVoters;
    }

    @Override
    final ExpressionBasedFilterInvocationSecurityMetadataSource createMetadataSource() {
        LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = createRequestMap();
        if(requestMap.isEmpty()) {
            throw new IllegalStateException("At least one mapping is required (i.e. authorizeUrls().anyRequest.authenticated())");
        }
        return new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, expressionHandler);
    }

    /**
     * Allows registering multiple {@link RequestMatcher} instances to a collection of {@link ConfigAttribute} instances
     *
     * @param requestMatchers the {@link RequestMatcher} instances to register to the {@link ConfigAttribute} instances
     * @param configAttributes the {@link ConfigAttribute} to be mapped by the {@link RequestMatcher} instances
     * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization.
     */
    private ExpressionUrlAuthorizationConfigurer<H> interceptUrl(Iterable<? extends RequestMatcher> requestMatchers, Collection<ConfigAttribute> configAttributes) {
        for(RequestMatcher requestMatcher : requestMatchers) {
            addMapping(new UrlMapping(requestMatcher, configAttributes));
        }
        return this;
    }

    private static String hasRole(String role) {
        Assert.notNull(role, "role cannot be null");
        if (role.startsWith("ROLE_")) {
            throw new IllegalArgumentException("role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
        }
        return "hasRole('ROLE_" + role + "')";
    }

    private static String hasAuthority(String authority) {
        return "hasAuthority('" + authority + "')";
    }

    private static String hasAnyAuthority(String... authorities) {
        String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','");
        return "hasAnyAuthority('" + anyAuthorities + "')";
    }

    private static String hasIpAddress(String ipAddressExpression) {
        return "hasIpAddress('" + ipAddressExpression + "')";
    }

    public final class AuthorizedUrl {
        private List<RequestMatcher> requestMatchers;
        private boolean not;

        /**
         * Creates a new instance
         *
         * @param requestMatchers the {@link RequestMatcher} instances to map
         */
        private AuthorizedUrl(List<RequestMatcher> requestMatchers) {
            this.requestMatchers = requestMatchers;
        }

        /**
         * Negates the following expression.
         *
         * @param role the role to require (i.e. USER, ADMIN, etc). Note, it should not start with "ROLE_" as
         *             this is automatically inserted.
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public AuthorizedUrl not() {
            this.not = true;
            return this;
        }

        /**
         * Shortcut for specifying URLs require a particular role. If you do not want to have "ROLE_" automatically
         * inserted see {@link #hasAuthority(String)}.
         *
         * @param role the role to require (i.e. USER, ADMIN, etc). Note, it should not start with "ROLE_" as
         *             this is automatically inserted.
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> hasRole(String role) {
            return access(ExpressionUrlAuthorizationConfigurer.hasRole(role));
        }

        /**
         * Specify that URLs require a particular authority.
         *
         * @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> hasAuthority(String authority) {
            return access(ExpressionUrlAuthorizationConfigurer.hasAuthority(authority));
        }

        /**
         * Specify that URLs requires any of a number authorities.
         *
         * @param authorities the requests require at least one of the authorities (i.e. "ROLE_USER","ROLE_ADMIN" would
         *                    mean either "ROLE_USER" or "ROLE_ADMIN" is required).
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> hasAnyAuthority(String... authorities) {
            return access(ExpressionUrlAuthorizationConfigurer.hasAnyAuthority(authorities));
        }

        /**
         * Specify that URLs requires a specific IP Address or
         * <a href="http://forum.springsource.org/showthread.php?102783-How-to-use-hasIpAddress&p=343971#post343971">subnet</a>.
         *
         * @param ipaddressExpression the ipaddress (i.e. 192.168.1.79) or local subnet (i.e. 192.168.0/24)
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> hasIpAddress(String ipaddressExpression) {
            return access(ExpressionUrlAuthorizationConfigurer.hasIpAddress(ipaddressExpression));
        }

        /**
         * Specify that URLs are allowed by anyone.
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> permitAll() {
            return access(permitAll);
        }

        /**
         * Specify that URLs are allowed by anonymous users.
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> anonymous() {
            return access(anonymous);
        }

        /**
         * Specify that URLs are allowed by users that have been remembered.
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         * @see {@link RememberMeConfigurer}
         */
        public ExpressionUrlAuthorizationConfigurer<H> rememberMe() {
            return access(rememberMe);
        }

        /**
         * Specify that URLs are not allowed by anyone.
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> denyAll() {
            return access(denyAll);
        }

        /**
         * Specify that URLs are allowed by any authenticated user.
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> authenticated() {
            return access(authenticated);
        }

        /**
         * Specify that URLs are allowed by users who have authenticated and were not "remembered".
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         * @see {@link RememberMeConfigurer}
         */
        public ExpressionUrlAuthorizationConfigurer<H> fullyAuthenticated() {
            return access(fullyAuthenticated);
        }

        /**
         * Allows specifying that URLs are secured by an arbitrary expression
         *
         * @param attribute the expression to secure the URLs (i.e. "hasRole('ROLE_USER') and hasRole('ROLE_SUPER')")
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further customization
         */
        public ExpressionUrlAuthorizationConfigurer<H> access(String attribute) {
            if(not) {
                attribute = "!" + attribute;
            }
            interceptUrl(requestMatchers, SecurityConfig.createList(attribute));
            return ExpressionUrlAuthorizationConfigurer.this;
        }
    }
}
TOP

Related Classes of org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer$AuthorizedUrl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.