org.geoserver.geoserver.authentication.filter.GeoFenceAuthFilter.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.geoserver.authentication.filter.GeoFenceAuthFilter.java

Source

/*
 *  Copyright (C) 2007 - 2013 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 3 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.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.geoserver.geoserver.authentication.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

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

import org.apache.commons.codec.binary.Base64;
import org.geoserver.geofence.services.RuleReaderService;
import org.geoserver.geofence.services.dto.AuthUser;
import org.geoserver.geoserver.authentication.auth.GeoFenceAuthenticationProvider;
import org.geoserver.geoserver.authentication.auth.GeoFenceSecurityProvider;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.config.SecurityNamedServiceConfig;
import org.geoserver.security.filter.GeoServerAuthenticationFilter;
import org.geoserver.security.filter.GeoServerCompositeFilter;
import org.geoserver.security.filter.GeoServerSecurityFilter;
import org.geoserver.security.impl.GeoServerRole;
import org.geotools.util.logging.Logging;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

/**
 *
 * @author ETj (etj at geo-solutions.it)
 */
public class GeoFenceAuthFilter
        //        extends GeoServerSecurityFilter
        extends GeoServerCompositeFilter implements GeoServerAuthenticationFilter {

    static final Logger LOGGER = Logging.getLogger(GeoFenceAuthFilter.class);

    private RuleReaderService ruleReaderService;
    private GeoFenceSecurityProvider geofenceAuth;

    //    static final String ROOT_ROLE = "ROLE_ADMINISTRATOR";
    //    static final String ANONYMOUS_ROLE = "ROLE_ANONYMOUS";
    static final String USER_ROLE = "ROLE_USER";

    private BasicAuthenticationEntryPoint aep;

    @Override
    public void initializeFromConfig(SecurityNamedServiceConfig config) throws IOException {
        super.initializeFromConfig(config);

        GeoFenceAuthFilterConfig cfg = (GeoFenceAuthFilterConfig) config;
        // anything to set here? maybe the cache config

        aep = new BasicAuthenticationEntryPoint();
        aep.setRealmName(GeoServerSecurityManager.REALM);

        try {
            aep.afterPropertiesSet();
        } catch (Exception e) {
            throw new IOException(e);
        }

        //        BasicAuthenticationFilterConfig authConfig = (BasicAuthenticationFilterConfig) config;
        SecurityNamedServiceConfig authCfg = securityManager.loadAuthenticationProviderConfig("geofence");
        GeoFenceAuthenticationProvider geofenceAuthProvider = geofenceAuth.createAuthenticationProvider(authCfg);
        BasicAuthenticationFilter filter = new BasicAuthenticationFilter(geofenceAuthProvider, aep);

        //        if (authConfig.isUseRememberMe()) {
        //            filter.setRememberMeServices(securityManager.getRememberMeService());
        //            GeoServerWebAuthenticationDetailsSource s = new GeoServerWebAuthenticationDetailsSource();
        //            filter.setAuthenticationDetailsSource(s);
        //        }
        filter.afterPropertiesSet();
        getNestedFilters().add(filter);
    }

    @Override
    public AuthenticationEntryPoint getAuthenticationEntryPoint() {
        return aep;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        request.setAttribute(GeoServerSecurityFilter.AUTHENTICATION_ENTRY_POINT_HEADER, aep);
        super.doFilter(request, response, chain);

        //        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        //        if (auth == null) {
        //            doAuth(request, response);
        //        } else {
        //            LOGGER.fine("Found existing Authentication in context: " + auth);
        //        }
        //
        //        chain.doFilter(request, response);
    }

    private void doAuth(ServletRequest request, ServletResponse response) {

        BasicUser basicUser = getBasicAuth(request);
        AuthUser authUser = null;

        if (basicUser != null) {
            LOGGER.fine("Checking auth for user " + basicUser.name);
            authUser = ruleReaderService.authorize(basicUser.name, basicUser.pw);

            if (authUser == null) {
                LOGGER.info("Could not authenticate user " + basicUser.name);
            }

        } else {
            LOGGER.fine("No basicauth");
        }

        if (authUser != null) {
            LOGGER.fine("Found user " + authUser);

            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            authorities.add(GeoServerRole.AUTHENTICATED_ROLE);

            if (authUser.getRole() == AuthUser.Role.ADMIN) {
                authorities.add(GeoServerRole.ADMIN_ROLE);
                authorities.add(new SimpleGrantedAuthority("ADMIN")); // needed for REST?!?
            } else {
                authorities.add(new SimpleGrantedAuthority(USER_ROLE)); // ??
            }

            UsernamePasswordAuthenticationToken upa = new UsernamePasswordAuthenticationToken(basicUser.name,
                    basicUser.pw, authorities);
            SecurityContextHolder.getContext().setAuthentication(upa);

        } else {
            LOGGER.fine("Anonymous access");
            //
            //            Authentication authentication = new AnonymousAuthenticationToken("geoserver", "null",
            //                    Arrays.asList(new GrantedAuthority[] { new SimpleGrantedAuthority(ANONYMOUS_ROLE) }));
            //            SecurityContextHolder.getContext().setAuthentication(authentication);

        }
    }

    /**
     * Simple username+password container
     */
    class BasicUser {
        String name;
        String pw;

        public BasicUser(String name, String pw) {
            this.name = name;
            this.pw = pw;
        }
    }

    /**
     * Reads username and password from Basic auth headers.
     * @return a BasicUser instance, or null if no basic auth detected.
     */
    private BasicUser getBasicAuth(ServletRequest request) {

        HttpServletRequest httpRequest = (HttpServletRequest) request;

        String header = ((httpRequest.getHeader("Authorization") != null) ? httpRequest.getHeader("Authorization")
                : httpRequest.getHeader("X-CUSTOM-USERID"));

        if (header != null) {
            String base64Token = header.startsWith("Basic ") ? header.substring(6) : header;
            String token = new String(Base64.decodeBase64(base64Token.getBytes()));

            int delim = token.indexOf(":");

            String username = null;
            String password = null;

            if (delim != -1) {
                username = token.substring(0, delim);
                password = token.substring(delim + 1);
            } else {
                username = header;
                password = null;
            }

            return new BasicUser(username, password);
        } else {
            return null;
        }

    }

    /**
     * @see org.geoserver.security.filter.GeoServerAuthenticationFilter#applicableForHtml()
     */
    //    @Override
    public boolean applicableForHtml() {
        return true;
    }

    /**
     * @see org.geoserver.security.filter.GeoServerAuthenticationFilter#applicableForServices()
     */
    //    @Override
    public boolean applicableForServices() {
        return true;
    }

    public void setRuleReaderService(RuleReaderService ruleReaderService) {
        this.ruleReaderService = ruleReaderService;
    }

    public void setGeofenceAuth(GeoFenceSecurityProvider geofenceAuth) {
        this.geofenceAuth = geofenceAuth;
    }

}