Package org.geoserver.security

Source Code of org.geoserver.security.GeoServerSecurityFilterChainProxy

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.security.config.SecurityManagerConfig;
import org.geoserver.security.filter.GeoServerAnonymousAuthenticationFilter;
import org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter;
import org.geotools.util.logging.Logging;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.AntPathRequestMatcher;
import org.springframework.security.web.util.RequestMatcher;

public class GeoServerSecurityFilterChainProxy extends FilterChainProxy
    implements SecurityManagerListener, ApplicationContextAware {
   
    static Logger LOGGER = Logging.getLogger("org.geoserver.security");

    static ThreadLocal<HttpServletRequest> REQUEST = new ThreadLocal<HttpServletRequest>();
   
    /**
     * Request header attribute indicating if the request was running through
     * a Geoserver security filter chain. The default is <code>false</code>.
     *
     * The mandatory {@link GeoServerSecurityContextPersistenceFilter} object
     * sets this attribute to <code>true</code>
     */
    public final static String SECURITY_ENABLED_ATTRIBUTE="org.geoserver.security.enabled";

    private boolean chainsInitialized;

    //security manager
    GeoServerSecurityManager securityManager;

    //app context
    ApplicationContext appContext;

    public GeoServerSecurityFilterChainProxy(GeoServerSecurityManager securityManager) {
        this.securityManager = securityManager;
        this.securityManager.addListener(this);
        chainsInitialized=false;
      
    }
   
/*   
    Map<String,List<String>> createDefaultFilterChain() {
        Map<String,List<String>> filterChain = new LinkedHashMap<String, List<String>>();
       
        filterChain.put("/web/**", Arrays.asList(SECURITY_CONTEXT_ASC_FILTER, LOGOUT_FILTER,
            FORM_LOGIN_FILTER, SERVLET_API_SUPPORT_FILTER, REMEMBER_ME_FILTER, ANONYMOUS_FILTER,
            EXCEPTION_TRANSLATION_FILTER, FILTER_SECURITY_INTERCEPTOR));

        filterChain.put("/j_spring_security_check/**", Arrays.asList(SECURITY_CONTEXT_ASC_FILTER,
            LOGOUT_FILTER, FORM_LOGIN_FILTER, SERVLET_API_SUPPORT_FILTER, REMEMBER_ME_FILTER,
            ANONYMOUS_FILTER, EXCEPTION_TRANSLATION_FILTER, FILTER_SECURITY_INTERCEPTOR));
       
        filterChain.put("/j_spring_security_logout/**", Arrays.asList(SECURITY_CONTEXT_ASC_FILTER,
            LOGOUT_FILTER, FORM_LOGIN_FILTER, SERVLET_API_SUPPORT_FILTER, REMEMBER_ME_FILTER,
            ANONYMOUS_FILTER, EXCEPTION_TRANSLATION_FILTER, FILTER_SECURITY_INTERCEPTOR));
       
        filterChain.put("/rest/**", Arrays.asList(SECURITY_CONTEXT_NO_ASC_FILTER, BASIC_AUTH_FILTER,
            ANONYMOUS_FILTER, EXCEPTION_TRANSLATION_OWS_FILTER, FILTER_SECURITY_REST_INTERCEPTOR));

        filterChain.put("/gwc/rest/web/**", Arrays.asList(ANONYMOUS_FILTER,
            EXCEPTION_TRANSLATION_FILTER, FILTER_SECURITY_INTERCEPTOR));

        filterChain.put("/gwc/rest/**", Arrays.asList(SECURITY_CONTEXT_NO_ASC_FILTER,
            BASIC_AUTH_NO_REMEMBER_ME_FILTER, EXCEPTION_TRANSLATION_OWS_FILTER,
            FILTER_SECURITY_REST_INTERCEPTOR));

        filterChain.put("/**", Arrays.asList(SECURITY_CONTEXT_NO_ASC_FILTER, ROLE_FILTER,BASIC_AUTH_FILTER,
            ANONYMOUS_FILTER, EXCEPTION_TRANSLATION_OWS_FILTER, FILTER_SECURITY_INTERCEPTOR));

        return filterChain;
    }
*/  
   
    /**
     * Returns <code>true</code> if the current {@link HttpServletRequest}
     * has traveled through a security filter chain.
     *
     * @return
     */
    static public boolean isSecurityEnabledForCurrentRequest() {
       
        if (REQUEST.get()==null) {
            return true;
        }
       
        if (Boolean.TRUE.equals(REQUEST.get().getAttribute(SECURITY_ENABLED_ATTRIBUTE)))
                return true;
       
        return false;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.appContext = applicationContext;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
       
        // assume security is disabled
        request.setAttribute(SECURITY_ENABLED_ATTRIBUTE, Boolean.FALSE);
        //set the request thread local
        REQUEST.set((HttpServletRequest) request);
        try {
            super.doFilter(request, response, chain);
        }
        finally {
            REQUEST.remove();
        }
    }

    @Override
    public void handlePostChanged(GeoServerSecurityManager securityManager) {
        createFilterChain();
    }

    public void afterPropertiesSet() {
        createFilterChain();
        super.afterPropertiesSet();
    };

    void createFilterChain() {

        if (!securityManager.isInitialized()) {
            //nothing to do
            return;
        }

        SecurityManagerConfig config = securityManager.getSecurityConfig();
        GeoServerSecurityFilterChain filterChain =
                new GeoServerSecurityFilterChain(config.getFilterChain());

        // similar to the list of authentication providers
        // adding required providers like GeoServerRootAuthenticationProvider
        filterChain.postConfigure(securityManager);

        Map<RequestMatcher,List<Filter>> filterChainMap =
                new LinkedHashMap<RequestMatcher,List<Filter>>();

        for (RequestFilterChain chain : filterChain.getRequestChains()) {
            RequestMatcher matcher = matcherForChain(chain);
            List<Filter> filters = new ArrayList<Filter>();
            for (String filterName : chain.getCompiledFilterNames()) {
                try {
                    Filter filter = lookupFilter(filterName);
                    if (filter == null) {
                        throw new NullPointerException("No filter named " + filterName +" could " +
                            "be found");
                    }
                    filters.add(filter);
                }
                catch(Exception ex) {
                    LOGGER.log(Level.SEVERE, "Error loading filter: " + filterName, ex);
                }
            }
            filterChainMap.put(matcher, filters);
        }
       

        synchronized (this) {
            // first, call destroy of all current filters       
            if (chainsInitialized) {
                for (SecurityFilterChain chain : getFilterChains()) {
                    for (Filter filter: chain.getFilters()) {
                        filter.destroy();
                    }
                }
            }
            // empty cache since filter config  will change
            securityManager.getAuthenticationCache().removeAll();

            // TODO Justin, this method is deprecated without replacement, I fear
            // this is a show stopper for the next spring security version, any idea
            setFilterChainMap(filterChainMap);
            chainsInitialized=true;
        }
    }

    /**
     * Creates a {@link GeoServerRequestMatcher} object for
     * the specified {@link RequestFilterChain}
     *
     * @param chain
     * @return
     */
    public GeoServerRequestMatcher matcherForChain(RequestFilterChain chain) {
       
        Set<HTTPMethod> methods = chain.getHttpMethods();
        if (chain.isMatchHTTPMethod()==false)
            methods=null;
       
        List<String> tmp =chain.getPatterns();
       
        if (tmp==null)
            return new GeoServerRequestMatcher(methods, (RequestMatcher[])null);
       
        // resolve multiple patterns separated by a comma
        List<String> patterns=new ArrayList<String>();
        for (String pattern : tmp) {
            String[] array = pattern.split(",");
            for (String singlePattern : array)
                patterns.add(singlePattern);
        }
       
        AntPathRequestMatcher[] matchers=new AntPathRequestMatcher[patterns.size()];
        for (int i = 0;i<matchers.length;i++) {
            matchers[i]=new AntPathRequestMatcher(patterns.get(i));
        }
        return new GeoServerRequestMatcher(methods,matchers);
    }
   
    /**
     * looks up a named filter 
     */
    public Filter lookupFilter(String filterName) throws IOException {
        Filter filter = securityManager.loadFilter(filterName);
        if (filter == null) {
            try {
                Object obj = GeoServerExtensions.bean(filterName, appContext);
                if (obj != null && obj instanceof Filter) {
                    filter = (Filter) obj;
                }
            } catch (NoSuchBeanDefinitionException ex) {
                  // do nothing
            }
        }
        return filter;
    }

    @Override
    public void destroy() {
        super.destroy();

        //do some cleanup
        securityManager.removeListener(this);
    }
   
    /**
     * Add constant filter chains
     *
     * @param filterChainMap
     */
    protected final void addConstantFilterChains(GeoServerSecurityFilterChain chain) {
    }
}
TOP

Related Classes of org.geoserver.security.GeoServerSecurityFilterChainProxy

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.