/* (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.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.security.config.ExceptionTranslationFilterConfig;
import org.geoserver.security.config.SecurityNamedServiceConfig;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.util.StringUtils;
/**
* Named Exception translation filter
*
* The {@link AuthenticationEntryPoint} is of type {@link DynamicAuthenticationEntryPoint}
*
* if {@link ExceptionTranslationFilterConfig#getAuthenticationEntryPointName()} is not empty,
* use this name for a lookup of an authentication filter and use the entry point of this
* filter.
*
*
* if the name is empty, use {@link GeoServerSecurityFilter#AUTHENTICATION_ENTRY_POINT_HEADER}
* as a servlet attribute name. Previous authentication filter should put an entry point in
* this attribute.
*
* if still no entry point was a found, use {@link Http403ForbiddenEntryPoint} as a default.
*
*
* @author mcr
*
*/
public class GeoServerExceptionTranslationFilter extends GeoServerCompositeFilter {
public static class DynamicAuthenticationEntryPoint implements AuthenticationEntryPoint {
protected AuthenticationEntryPoint defaultEntryPoint = new Http403ForbiddenEntryPoint();
protected AuthenticationEntryPoint entryEntryPoint=null;
public AuthenticationEntryPoint getEntryEntryPoint() {
return entryEntryPoint;
}
public void setEntryEntryPoint(AuthenticationEntryPoint entryEntryPoint) {
this.entryEntryPoint = entryEntryPoint;
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
AuthenticationEntryPoint aep = (AuthenticationEntryPoint)
request.getAttribute(GeoServerSecurityFilter.AUTHENTICATION_ENTRY_POINT_HEADER);
if (aep!=null) // remove from request
request.removeAttribute(AUTHENTICATION_ENTRY_POINT_HEADER);
// entry point specified ?
if (getEntryEntryPoint()!=null) {
getEntryEntryPoint().commence(request, response, authException);
return;
}
// entry point from request ?
if (aep!=null) {
aep.commence(request, response, authException);
return;
}
// 403, FORBIDDEN
defaultEntryPoint.commence(request, response, authException);
}
};
@Override
public void initializeFromConfig(SecurityNamedServiceConfig config) throws IOException {
super.initializeFromConfig(config);
ExceptionTranslationFilterConfig authConfig =
(ExceptionTranslationFilterConfig) config;
DynamicAuthenticationEntryPoint ep = new DynamicAuthenticationEntryPoint();
if (StringUtils.hasLength(authConfig.getAuthenticationFilterName())) {
GeoServerSecurityFilter authFilter = getSecurityManager().loadFilter(authConfig.getAuthenticationFilterName());
ep.setEntryEntryPoint(authFilter.getAuthenticationEntryPoint());
}
HttpSessionRequestCache cache = new HttpSessionRequestCache();
cache.setCreateSessionAllowed(false);
ExceptionTranslationFilter filter = new ExceptionTranslationFilter(ep,cache);
AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();
if (StringUtils.hasLength(authConfig.getAccessDeniedErrorPage())) {
// check if page exists
if (GeoServerExtensions.file(authConfig.getAccessDeniedErrorPage())!=null)
accessDeniedHandler.setErrorPage(authConfig.getAccessDeniedErrorPage());
else
LOGGER.warning("Cannot find: "+ authConfig.getAccessDeniedErrorPage());
}
filter.setAccessDeniedHandler(accessDeniedHandler);
filter.afterPropertiesSet();
getNestedFilters().add(filter);
}
}