SEC-2249: AbstractSecurityWebApplicationInitializer allows register config

This commit is contained in:
Rob Winch 2013-08-06 15:01:44 -05:00
parent 976d9a9016
commit e8278f3b9b
4 changed files with 79 additions and 50 deletions

View File

@ -1,37 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.samples.config;
import org.springframework.web.context.AbstractContextLoaderInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
/**
* @author Rob Winch
*
*/
public class RootContextApplicationInitializer extends AbstractContextLoaderInitializer {
/* (non-Javadoc)
* @see org.springframework.web.context.AbstractContextLoaderInitializer#createRootApplicationContext()
*/
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(SecurityConfig.class);
return context;
}
}

View File

@ -23,4 +23,8 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn
* @author Rob Winch
*/
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityConfig.class);
}
}

View File

@ -35,14 +35,18 @@ import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.util.Assert;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.AbstractContextLoaderInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
/**
* Registers the {@link DelegatingFilterProxy} to use the
* springSecurityFilterChain before any other registered {@link Filter}. This
* class is typically used in addition to a subclass of
* {@link AbstractContextLoaderInitializer}.
* springSecurityFilterChain before any other registered {@link Filter}. When
* used with {@link #AbstractSecurityWebApplicationInitializer(Class...)}, it
* will also register a {@link ContextLoaderListener}. When used with
* {@link #AbstractSecurityWebApplicationInitializer()}, this class is typically
* used in addition to a subclass of {@link AbstractContextLoaderInitializer}.
*
* <p>
* By default the {@link DelegatingFilterProxy} is registered without support,
@ -53,7 +57,6 @@ import org.springframework.web.filter.DelegatingFilterProxy;
* <p>
* Additional configuration before and after the springSecurityFilterChain can
* be added by overriding
* {@link #beforeSpringSecurityFilterChain(ServletContext)} and
* {@link #afterSpringSecurityFilterChain(ServletContext)}.
* </p>
*
@ -77,11 +80,37 @@ public abstract class AbstractSecurityWebApplicationInitializer implements WebAp
public static final String DEFAULT_FILTER_NAME = "springSecurityFilterChain";
private WebApplicationInitializer contextLoaderListenerInitializer;
/**
* Creates a new instance that assumes the Spring Security configuration is
* loaded by some other means than this class. For example, a user might
* create a {@link ContextLoaderListener} using a subclass of
* {@link AbstractContextLoaderInitializer}.
*
* @see ContextLoaderListener
*/
protected AbstractSecurityWebApplicationInitializer() {
}
/**
* Creates a new instance that will instantiate the
* {@link ContextLoaderListener} with the specified classes.
*
* @param configurationClasses
*/
protected AbstractSecurityWebApplicationInitializer(Class<?>... configurationClasses) {
contextLoaderListenerInitializer = new RootContextApplicationInitializer(configurationClasses){};
}
/* (non-Javadoc)
* @see org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet.ServletContext)
*/
public final void onStartup(ServletContext servletContext)
throws ServletException {
if(contextLoaderListenerInitializer != null) {
contextLoaderListenerInitializer.onStartup(servletContext);
}
if(enableHttpSessionEventPublisher()) {
servletContext.addListener("org.springframework.security.web.session.HttpSessionEventPublisher");
}
@ -281,4 +310,21 @@ public abstract class AbstractSecurityWebApplicationInitializer implements WebAp
return true;
}
private static abstract class RootContextApplicationInitializer extends AbstractContextLoaderInitializer {
private Class<?>[] configurationClasses;
private RootContextApplicationInitializer(Class<?>... configurationClasses) {
this.configurationClasses = configurationClasses;
}
/* (non-Javadoc)
* @see org.springframework.web.context.AbstractContextLoaderInitializer#createRootApplicationContext()
*/
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(configurationClasses);
return context;
}
}
}

View File

@ -15,16 +15,16 @@
*/
package org.springframework.security.web.context;
import java.util.EnumSet;
import javax.servlet.DispatcherType
import javax.servlet.Filter
import javax.servlet.FilterRegistration
import javax.servlet.ServletContext
import javax.servlet.SessionTrackingMode
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.SessionTrackingMode;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.context.annotation.Configuration
import org.springframework.security.web.session.HttpSessionEventPublisher
import org.springframework.web.context.ContextLoaderListener
import org.springframework.web.filter.DelegatingFilterProxy
import spock.lang.Specification
@ -47,6 +47,22 @@ class AbstractSecurityWebApplicationInitializerTests extends Specification {
0 * context.addListener(_)
}
def "defaults with ContextLoaderListener"() {
setup:
ServletContext context = Mock()
FilterRegistration.Dynamic registration = Mock()
when:
new AbstractSecurityWebApplicationInitializer(MyRootConfiguration){}.onStartup(context)
then:
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration
1 * registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR), false, "/*");
1 * registration.setAsyncSupported(true)
1 * context.addListener(_ as ContextLoaderListener)
}
@Configuration
static class MyRootConfiguration {}
def "enableHttpSessionEventPublisher() = true"() {
setup:
ServletContext context = Mock()