9 changed files with 31 additions and 413 deletions
@ -1,44 +0,0 @@
@@ -1,44 +0,0 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.config.RuntimeBeanReference; |
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition; |
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.security.web.authentication.www.BasicProcessingFilter; |
||||
import org.springframework.security.web.authentication.www.BasicProcessingFilterEntryPoint; |
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* Creates a {@link BasicProcessingFilter} and {@link BasicProcessingFilterEntryPoint} and |
||||
* registers them in the application context. |
||||
* |
||||
* @author Luke Taylor |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
public class BasicAuthenticationBeanDefinitionParser implements BeanDefinitionParser { |
||||
private String realmName; |
||||
|
||||
public BasicAuthenticationBeanDefinitionParser(String realmName) { |
||||
this.realmName = realmName; |
||||
} |
||||
|
||||
public BeanDefinition parse(Element elt, ParserContext parserContext) { |
||||
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(BasicProcessingFilter.class); |
||||
RootBeanDefinition entryPoint = new RootBeanDefinition(BasicProcessingFilterEntryPoint.class); |
||||
entryPoint.setSource(parserContext.extractSource(elt)); |
||||
entryPoint.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); |
||||
|
||||
entryPoint.getPropertyValues().addPropertyValue("realmName", realmName); |
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT, entryPoint); |
||||
|
||||
filterBuilder.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER)); |
||||
filterBuilder.addPropertyValue("authenticationEntryPoint", new RuntimeBeanReference(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT)); |
||||
|
||||
return filterBuilder.getBeanDefinition(); |
||||
} |
||||
} |
||||
@ -1,60 +0,0 @@
@@ -1,60 +0,0 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.BeanFactory; |
||||
import org.springframework.beans.factory.BeanFactoryAware; |
||||
import org.springframework.beans.factory.config.BeanPostProcessor; |
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||
import org.springframework.security.web.AuthenticationEntryPoint; |
||||
import org.springframework.security.web.access.ExceptionTranslationFilter; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* |
||||
* @author Luke Taylor |
||||
* @since 2.0.2 |
||||
*/ |
||||
public class EntryPointInjectionBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { |
||||
private final Log logger = LogFactory.getLog(getClass()); |
||||
private ConfigurableListableBeanFactory beanFactory; |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { |
||||
// if (!BeanIds.EXCEPTION_TRANSLATION_FILTER.equals(beanName)) {
|
||||
// return bean;
|
||||
// }
|
||||
//
|
||||
// logger.info("Selecting AuthenticationEntryPoint for use in ExceptionTranslationFilter");
|
||||
//
|
||||
// ExceptionTranslationFilter etf = (ExceptionTranslationFilter) beanFactory.getBean(BeanIds.EXCEPTION_TRANSLATION_FILTER);
|
||||
//
|
||||
// Object entryPoint = null;
|
||||
//
|
||||
// if (beanFactory.containsBean(BeanIds.MAIN_ENTRY_POINT)) {
|
||||
// entryPoint = beanFactory.getBean(BeanIds.MAIN_ENTRY_POINT);
|
||||
// logger.info("Using main configured AuthenticationEntryPoint.");
|
||||
// } else {
|
||||
// Map entryPoints = beanFactory.getBeansOfType(AuthenticationEntryPoint.class);
|
||||
// Assert.isTrue(entryPoints.size() != 0, "No AuthenticationEntryPoint instances defined");
|
||||
// Assert.isTrue(entryPoints.size() == 1, "More than one AuthenticationEntryPoint defined in context");
|
||||
// entryPoint = entryPoints.values().toArray()[0];
|
||||
// }
|
||||
//
|
||||
// logger.info("Using bean '" + entryPoint + "' as the entry point.");
|
||||
// etf.setAuthenticationEntryPoint((AuthenticationEntryPoint) entryPoint);
|
||||
|
||||
return bean; |
||||
} |
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { |
||||
return bean; |
||||
} |
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; |
||||
} |
||||
} |
||||
@ -1,190 +0,0 @@
@@ -1,190 +0,0 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import java.util.List; |
||||
|
||||
import javax.servlet.Filter; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.BeanFactory; |
||||
import org.springframework.beans.factory.BeanFactoryAware; |
||||
import org.springframework.beans.factory.ListableBeanFactory; |
||||
import org.springframework.beans.factory.config.BeanPostProcessor; |
||||
import org.springframework.security.web.FilterChainProxy; |
||||
import org.springframework.security.web.access.ExceptionTranslationFilter; |
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; |
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter; |
||||
import org.springframework.security.web.authentication.www.BasicProcessingFilter; |
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter; |
||||
import org.springframework.security.web.session.SessionFixationProtectionFilter; |
||||
import org.springframework.security.web.wrapper.SecurityContextHolderAwareRequestFilter; |
||||
|
||||
/** |
||||
* |
||||
* @author Luke Taylor |
||||
* @version $Id$ |
||||
* @since 2.0 |
||||
*/ |
||||
public class FilterChainProxyPostProcessor implements BeanPostProcessor, BeanFactoryAware { |
||||
private Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private ListableBeanFactory beanFactory; |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { |
||||
// if(!BeanIds.FILTER_CHAIN_PROXY.equals(beanName)) {
|
||||
// return bean;
|
||||
// }
|
||||
//
|
||||
// FilterChainProxy filterChainProxy = (FilterChainProxy) bean;
|
||||
// FilterChainList filterList = (FilterChainList) beanFactory.getBean(BeanIds.FILTER_LIST);
|
||||
//
|
||||
// List<Filter> filters = new ArrayList<Filter>(filterList.getFilters());
|
||||
// Collections.sort(filters, new OrderComparator());
|
||||
//
|
||||
// logger.info("Checking sorted filter chain: " + filters);
|
||||
//
|
||||
// for(int i=0; i < filters.size(); i++) {
|
||||
// Ordered filter = (Ordered)filters.get(i);
|
||||
//
|
||||
// if (i > 0) {
|
||||
// Ordered previous = (Ordered)filters.get(i-1);
|
||||
// if (filter.getOrder() == previous.getOrder()) {
|
||||
// throw new SecurityConfigurationException("Filters '" + unwrapFilter(filter) + "' and '" +
|
||||
// unwrapFilter(previous) + "' have the same 'order' value. When using custom filters, " +
|
||||
// "please make sure the positions do not conflict with default filters. " +
|
||||
// "Alternatively you can disable the default filters by removing the corresponding " +
|
||||
// "child elements from <http> and avoiding the use of <http auto-config='true'>.");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// logger.info("Filter chain...");
|
||||
// for (int i=0; i < filters.size(); i++) {
|
||||
// // Remove the ordered wrapper from the filter and put it back in the chain at the same position.
|
||||
// Filter filter = unwrapFilter(filters.get(i));
|
||||
// logger.info("[" + i + "] - " + filter);
|
||||
// filters.set(i, filter);
|
||||
// }
|
||||
//
|
||||
// checkFilterStack(filters);
|
||||
//
|
||||
// // Note that this returns a copy
|
||||
// Map<String, List<Filter>> filterMap = filterChainProxy.getFilterChainMap();
|
||||
// filterMap.put(filterChainProxy.getMatcher().getUniversalMatchPattern(), filters);
|
||||
// filterChainProxy.setFilterChainMap(filterMap);
|
||||
//
|
||||
// checkLoginPageIsntProtected(filterChainProxy);
|
||||
//
|
||||
// logger.info("FilterChainProxy: " + filterChainProxy);
|
||||
|
||||
return bean; |
||||
} |
||||
|
||||
/** |
||||
* Checks the filter list for possible errors and logs them |
||||
*/ |
||||
private void checkFilterStack(List<Filter> filters) { |
||||
checkForDuplicates(SecurityContextPersistenceFilter.class, filters); |
||||
checkForDuplicates(UsernamePasswordAuthenticationProcessingFilter.class, filters); |
||||
checkForDuplicates(SessionFixationProtectionFilter.class, filters); |
||||
checkForDuplicates(BasicProcessingFilter.class, filters); |
||||
checkForDuplicates(SecurityContextHolderAwareRequestFilter.class, filters); |
||||
checkForDuplicates(ExceptionTranslationFilter.class, filters); |
||||
checkForDuplicates(FilterSecurityInterceptor.class, filters); |
||||
} |
||||
|
||||
private void checkForDuplicates(Class<? extends Filter> clazz, List<Filter> filters) { |
||||
for (int i=0; i < filters.size(); i++) { |
||||
Filter f1 = filters.get(i); |
||||
if (clazz.isAssignableFrom(f1.getClass())) { |
||||
// Found the first one, check remaining for another
|
||||
for (int j=i+1; j < filters.size(); j++) { |
||||
Filter f2 = filters.get(j); |
||||
if (clazz.isAssignableFrom(f2.getClass())) { |
||||
logger.warn("Possible error: Filters at position " + i + " and " + j + " are both " + |
||||
"instances of " + clazz.getName()); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Checks for the common error of having a login page URL protected by the security interceptor */ |
||||
private void checkLoginPageIsntProtected(FilterChainProxy fcp) { |
||||
// ExceptionTranslationFilter etf = (ExceptionTranslationFilter) beanFactory.getBean(BeanIds.EXCEPTION_TRANSLATION_FILTER);
|
||||
//
|
||||
// if (etf.getAuthenticationEntryPoint() instanceof LoginUrlAuthenticationEntryPoint) {
|
||||
// String loginPage =
|
||||
// ((LoginUrlAuthenticationEntryPoint)etf.getAuthenticationEntryPoint()).getLoginFormUrl();
|
||||
// List<Filter> filters = fcp.getFilters(loginPage);
|
||||
// logger.info("Checking whether login URL '" + loginPage + "' is accessible with your configuration");
|
||||
//
|
||||
// if (filters == null || filters.isEmpty()) {
|
||||
// logger.debug("Filter chain is empty for the login page");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (loginPage.equals(DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL) &&
|
||||
// beanFactory.containsBean(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER)) {
|
||||
// logger.debug("Default generated login page is in use");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// FilterSecurityInterceptor fsi =
|
||||
// ((FilterSecurityInterceptor)beanFactory.getBean(BeanIds.FILTER_SECURITY_INTERCEPTOR));
|
||||
// DefaultFilterInvocationSecurityMetadataSource fids =
|
||||
// (DefaultFilterInvocationSecurityMetadataSource) fsi.getSecurityMetadataSource();
|
||||
// List<ConfigAttribute> attributes = fids.lookupAttributes(loginPage, "POST");
|
||||
//
|
||||
// if (attributes == null) {
|
||||
// logger.debug("No access attributes defined for login page URL");
|
||||
// if (fsi.isRejectPublicInvocations()) {
|
||||
// logger.warn("FilterSecurityInterceptor is configured to reject public invocations." +
|
||||
// " Your login page may not be accessible.");
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (!beanFactory.containsBean(BeanIds.ANONYMOUS_PROCESSING_FILTER)) {
|
||||
// logger.warn("The login page is being protected by the filter chain, but you don't appear to have" +
|
||||
// " anonymous authentication enabled. This is almost certainly an error.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // Simulate an anonymous access with the supplied attributes.
|
||||
// AnonymousProcessingFilter anonPF = (AnonymousProcessingFilter) beanFactory.getBean(BeanIds.ANONYMOUS_PROCESSING_FILTER);
|
||||
// AnonymousAuthenticationToken token =
|
||||
// new AnonymousAuthenticationToken("key", anonPF.getUserAttribute().getPassword(),
|
||||
// anonPF.getUserAttribute().getAuthorities());
|
||||
// try {
|
||||
// fsi.getAccessDecisionManager().decide(token, new Object(), fids.lookupAttributes(loginPage, "POST"));
|
||||
// } catch (Exception e) {
|
||||
// logger.warn("Anonymous access to the login page doesn't appear to be enabled. This is almost certainly " +
|
||||
// "an error. Please check your configuration allows unauthenticated access to the configured " +
|
||||
// "login page. (Simulated access was rejected: " + e + ")");
|
||||
// }
|
||||
// }
|
||||
} |
||||
|
||||
/** |
||||
* Returns the delegate filter of a wrapper, or the unchanged filter if it isn't wrapped. |
||||
*/ |
||||
private Filter unwrapFilter(Object filter) { |
||||
if (filter instanceof OrderedFilterBeanDefinitionDecorator.OrderedFilterDecorator) { |
||||
return ((OrderedFilterBeanDefinitionDecorator.OrderedFilterDecorator)filter).getDelegate(); |
||||
} |
||||
|
||||
return (Filter) filter; |
||||
} |
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { |
||||
return bean; |
||||
} |
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
||||
this.beanFactory = (ListableBeanFactory) beanFactory; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue