/* (c) 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.security.onelogin;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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.security.filter.AuthenticationCachingFilter;
import org.geoserver.security.filter.GeoServerPreAuthenticatedUserNameFilter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Authentication Filter that add to {@link #GeoServerPreAuthenticatedUserNameFilter} the feature of {@link #GeoServerCompositeFilter} to nested
* {@link Filter} objects
*
* @author Xandros
*/
public abstract class GeoServerPreAuthenticatedCompositeUserNameFilter
extends GeoServerPreAuthenticatedUserNameFilter {
public final static String CACHE_KEY_ATTRIBUTE = "_geoserver_security_cache_key";
public final static String CACHE_KEY_IDLE_SECS = "_geoserver_security_cache_key_idle_secs";
public final static String CACHE_KEY_LIVE_SECS = "_geoserver_security_cache_key_live_secs";
protected class NestedFilterChain implements FilterChain {
private final FilterChain originalChain;
private int currentPosition = 0;
private NestedFilterChain(FilterChain chain) {
this.originalChain = chain;
}
public void doFilter(final ServletRequest request, final ServletResponse response)
throws IOException, ServletException {
// try cache
if (GeoServerPreAuthenticatedCompositeUserNameFilter.this instanceof AuthenticationCachingFilter
&& currentPosition == 0) {
String cacheKey = authenticateFromCache(
(AuthenticationCachingFilter) GeoServerPreAuthenticatedCompositeUserNameFilter.this,
(HttpServletRequest) request);
if (cacheKey != null)
request.setAttribute(CACHE_KEY_ATTRIBUTE, cacheKey);
}
if (nestedFilters == null || currentPosition == nestedFilters.size()) {
Authentication postAuthentication = SecurityContextHolder.getContext()
.getAuthentication();
String cacheKey = (String) request.getAttribute(CACHE_KEY_ATTRIBUTE);
if (postAuthentication != null && cacheKey != null) {
Integer idleSecs = (Integer) request.getAttribute(CACHE_KEY_IDLE_SECS);
Integer liveSecs = (Integer) request.getAttribute(CACHE_KEY_LIVE_SECS);
getSecurityManager().getAuthenticationCache().put(getName(), cacheKey,
postAuthentication, idleSecs, liveSecs);
}
// clean up request attributes in any case,
request.setAttribute(CACHE_KEY_ATTRIBUTE, null);
request.setAttribute(CACHE_KEY_IDLE_SECS, null);
request.setAttribute(CACHE_KEY_LIVE_SECS, null);
// GeoServerPreAuthenticatedCompositeUserNameFilter.super.doFilter(request, response, originalChain);
originalChain.doFilter(request, response);
} else {
currentPosition++;
Filter nextFilter = nestedFilters.get(currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
}
protected List<Filter> nestedFilters = new ArrayList<Filter>();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (nestedFilters == null || nestedFilters.size() == 0) {
chain.doFilter(request, response);
return;
}
NestedFilterChain nestedChain = new NestedFilterChain(chain);
nestedChain.doFilter(request, response);
}
public List<Filter> getNestedFilters() {
return nestedFilters;
}
public void setNestedFilters(List<Filter> nestedFilters) {
this.nestedFilters = nestedFilters;
}
}