2 changed files with 447 additions and 308 deletions
@ -1,308 +0,0 @@
@@ -1,308 +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 |
||||
* |
||||
* https://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.web.context; |
||||
|
||||
import javax.servlet.DispatcherType |
||||
import javax.servlet.Filter |
||||
import javax.servlet.FilterRegistration |
||||
import javax.servlet.ServletContext |
||||
import javax.servlet.SessionTrackingMode |
||||
|
||||
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 |
||||
|
||||
/** |
||||
* @author Rob Winch |
||||
* |
||||
*/ |
||||
class AbstractSecurityWebApplicationInitializerTests extends Specification { |
||||
def DEFAULT_DISPATCH = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC) |
||||
|
||||
def defaults() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
1 * registration.setAsyncSupported(true) |
||||
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(DEFAULT_DISPATCH, false, "/*"); |
||||
1 * registration.setAsyncSupported(true) |
||||
1 * context.addListener(_ as ContextLoaderListener) |
||||
} |
||||
|
||||
@Configuration |
||||
static class MyRootConfiguration {} |
||||
|
||||
def "enableHttpSessionEventPublisher() = true"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected boolean enableHttpSessionEventPublisher() { |
||||
return true; |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
1 * registration.setAsyncSupported(true) |
||||
1 * context.addListener(HttpSessionEventPublisher.class.name) |
||||
} |
||||
|
||||
def "custom getSecurityDispatcherTypes()"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected EnumSet<DispatcherType> getSecurityDispatcherTypes() { |
||||
return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.FORWARD); |
||||
} |
||||
}.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, DispatcherType.FORWARD), false, "/*"); |
||||
1 * registration.setAsyncSupported(true) |
||||
0 * context.addListener(_) |
||||
} |
||||
|
||||
def "custom getDispatcherWebApplicationContextSuffix"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected String getDispatcherWebApplicationContextSuffix() { |
||||
return "dispatcher" |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == "org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher"}) >> registration |
||||
1 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
1 * registration.setAsyncSupported(true) |
||||
0 * context.addListener(_) |
||||
} |
||||
|
||||
def "springSecurityFilterChain already registered"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> null |
||||
IllegalStateException success = thrown() |
||||
success.message == "Duplicate Filter registration for 'springSecurityFilterChain'. Check to ensure the Filter is only configured once." |
||||
} |
||||
|
||||
def "insertFilters"() { |
||||
setup: |
||||
Filter filter1 = Mock() |
||||
Filter filter2 = Mock() |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context, filter1, filter2); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
3 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
3 * registration.setAsyncSupported(true) |
||||
0 * context.addListener(_) |
||||
1 * context.addFilter(_, filter1) >> registration |
||||
1 * context.addFilter(_, filter2) >> registration |
||||
} |
||||
|
||||
def "insertFilters already registered"() { |
||||
setup: |
||||
Filter filter1 = Mock() |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context, filter1); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
1 * context.addFilter(_, filter1) >> null |
||||
IllegalStateException success = thrown() |
||||
success.message == "Duplicate Filter registration for 'filter'. Check to ensure the Filter is only configured once." |
||||
} |
||||
|
||||
def "insertFilters no filters"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
IllegalArgumentException success = thrown() |
||||
success.message == "filters cannot be null or empty" |
||||
} |
||||
|
||||
def "insertFilters filters with null"() { |
||||
setup: |
||||
Filter filter1 = Mock() |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context, filter1, null); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
2 * context.addFilter(_, _) >> registration |
||||
IllegalArgumentException success = thrown() |
||||
success.message == "filters cannot contain null values. Got [Mock for type 'Filter' named 'filter1', null]" |
||||
} |
||||
|
||||
def "appendFilters"() { |
||||
setup: |
||||
Filter filter1 = Mock() |
||||
Filter filter2 = Mock() |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context,filter1, filter2); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
2 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, true, "/*"); |
||||
3 * registration.setAsyncSupported(true) |
||||
0 * context.addListener(_) |
||||
1 * context.addFilter(_, filter1) >> registration |
||||
1 * context.addFilter(_, filter2) >> registration |
||||
} |
||||
|
||||
def "appendFilters already registered"() { |
||||
setup: |
||||
Filter filter1 = Mock() |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context, filter1); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * registration.addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
1 * context.addFilter(_, filter1) >> null |
||||
IllegalStateException success = thrown() |
||||
success.message == "Duplicate Filter registration for 'filter'. Check to ensure the Filter is only configured once." |
||||
} |
||||
|
||||
def "appendFilters no filters"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
IllegalArgumentException success = thrown() |
||||
success.message == "filters cannot be null or empty" |
||||
} |
||||
|
||||
def "sessionTrackingModes defaults"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ }.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * context.setSessionTrackingModes({Set<SessionTrackingMode> modes -> modes.size() == 1 && modes.containsAll([SessionTrackingMode.COOKIE]) }) |
||||
} |
||||
|
||||
def "sessionTrackingModes override"() { |
||||
setup: |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
@Override |
||||
public Set<SessionTrackingMode> getSessionTrackingModes() { |
||||
return [SessionTrackingMode.SSL] |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration |
||||
1 * context.setSessionTrackingModes({Set<SessionTrackingMode> modes -> modes.size() == 1 && modes.containsAll([SessionTrackingMode.SSL]) }) |
||||
} |
||||
|
||||
def "appendFilters filters with null"() { |
||||
setup: |
||||
Filter filter1 = Mock() |
||||
ServletContext context = Mock() |
||||
FilterRegistration.Dynamic registration = Mock() |
||||
when: |
||||
new AbstractSecurityWebApplicationInitializer(){ |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context, filter1, null); |
||||
} |
||||
}.onStartup(context) |
||||
then: |
||||
2 * context.addFilter(_, _) >> registration |
||||
IllegalArgumentException success = thrown() |
||||
success.message == "filters cannot contain null values. Got [Mock for type 'Filter' named 'filter1', null]" |
||||
} |
||||
|
||||
def "DEFAULT_FILTER_NAME == springSecurityFilterChain"() { |
||||
expect: |
||||
AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME == "springSecurityFilterChain" |
||||
} |
||||
} |
||||
@ -0,0 +1,447 @@
@@ -0,0 +1,447 @@
|
||||
/* |
||||
* 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 |
||||
* |
||||
* https://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.web.context; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.EnumSet; |
||||
import java.util.EventListener; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
import javax.servlet.DispatcherType; |
||||
import javax.servlet.Filter; |
||||
import javax.servlet.FilterRegistration; |
||||
import javax.servlet.ServletContext; |
||||
import javax.servlet.SessionTrackingMode; |
||||
|
||||
import org.junit.Test; |
||||
import org.mockito.ArgumentCaptor; |
||||
|
||||
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 static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatCode; |
||||
import static org.mockito.ArgumentMatchers.any; |
||||
import static org.mockito.ArgumentMatchers.anyString; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.Mockito.doNothing; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.powermock.api.mockito.PowerMockito.when; |
||||
|
||||
/** |
||||
* @author Rob Winch |
||||
* @author Josh Cummings |
||||
*/ |
||||
public class AbstractSecurityWebApplicationInitializerTests { |
||||
private static final EnumSet<DispatcherType> DEFAULT_DISPATCH = |
||||
EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC); |
||||
|
||||
@Test |
||||
public void onStartupWhenDefaultContextThenRegistersSpringSecurityFilterChain() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() {}.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(registration).setAsyncSupported(true); |
||||
verifyNoAddListener(context); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenConfigurationClassThenAddsContextLoaderListener() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer(MyRootConfiguration.class) {}.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(registration).setAsyncSupported(true); |
||||
verify(context).addListener(any(ContextLoaderListener.class)); |
||||
} |
||||
|
||||
@Configuration |
||||
static class MyRootConfiguration {} |
||||
|
||||
@Test |
||||
public void onStartupWhenEnableHttpSessionEventPublisherIsTrueThenAddsHttpSessionEventPublisher() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected boolean enableHttpSessionEventPublisher() { |
||||
return true; |
||||
} |
||||
}.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(registration).setAsyncSupported(true); |
||||
verify(context).addListener(HttpSessionEventPublisher.class.getName()); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenCustomSecurityDispatcherTypesThenUses() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected EnumSet<DispatcherType> getSecurityDispatcherTypes() { |
||||
return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.FORWARD); |
||||
} |
||||
}.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.FORWARD), false, "/*"); |
||||
verify(registration).setAsyncSupported(true); |
||||
verifyNoAddListener(context); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenCustomDispatcherWebApplicationContextSuffixThenUses() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected String getDispatcherWebApplicationContextSuffix() { |
||||
return "dispatcher"; |
||||
} |
||||
}.onStartup(context); |
||||
|
||||
DelegatingFilterProxy proxy = proxyCaptor.getValue(); |
||||
assertThat(proxy.getContextAttribute()) |
||||
.isEqualTo("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher"); |
||||
assertThat(proxy).hasFieldOrPropertyWithValue("targetBeanName", "springSecurityFilterChain"); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(registration).setAsyncSupported(true); |
||||
verifyNoAddListener(context); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenSpringSecurityFilterChainAlreadyRegisteredThenException() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() {}.onStartup(context)) |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Duplicate Filter registration for 'springSecurityFilterChain'. " + |
||||
"Check to ensure the Filter is only configured once."); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenInsertFiltersThenInserted() { |
||||
Filter filter1 = mock(Filter.class); |
||||
Filter filter2 = mock(Filter.class); |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
when(context.addFilter(anyString(), eq(filter1))).thenReturn(registration); |
||||
when(context.addFilter(anyString(), eq(filter2))).thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context, filter1, filter2); |
||||
} |
||||
}.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration, times(3)).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(registration, times(3)).setAsyncSupported(true); |
||||
verifyNoAddListener(context); |
||||
verify(context).addFilter(anyString(), eq(filter1)); |
||||
verify(context).addFilter(anyString(), eq(filter2)); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenDuplicateFilterInsertedThenException() { |
||||
Filter filter1 = mock(Filter.class); |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context, filter1); |
||||
} |
||||
}.onStartup(context)) |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Duplicate Filter registration for 'object'. " + |
||||
"Check to ensure the Filter is only configured once."); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(context).addFilter(anyString(), eq(filter1)); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenInsertFiltersEmptyThenException() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context); |
||||
} |
||||
}.onStartup(context)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("filters cannot be null or empty"); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenNullFilterInsertedThenException() { |
||||
Filter filter = mock(Filter.class); |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
when(context.addFilter(anyString(), eq(filter))).thenReturn(registration); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
insertFilters(context, filter, null); |
||||
} |
||||
}.onStartup(context)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("filters cannot contain null values"); |
||||
|
||||
verify(context, times(2)).addFilter(anyString(), any(Filter.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenAppendFiltersThenAppended() { |
||||
Filter filter1 = mock(Filter.class); |
||||
Filter filter2 = mock(Filter.class); |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
when(context.addFilter(anyString(), eq(filter1))).thenReturn(registration); |
||||
when(context.addFilter(anyString(), eq(filter2))).thenReturn(registration); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context, filter1, filter2); |
||||
} |
||||
}.onStartup(context); |
||||
|
||||
verify(registration, times(1)).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(registration, times(2)).addMappingForUrlPatterns(DEFAULT_DISPATCH, true, "/*"); |
||||
verify(registration, times(3)).setAsyncSupported(true); |
||||
verifyNoAddListener(context); |
||||
verify(context, times(3)).addFilter(anyString(), any(Filter.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenDuplicateFilterAppendedThenException() { |
||||
Filter filter1 = mock(Filter.class); |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context, filter1); |
||||
} |
||||
}.onStartup(context)) |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Duplicate Filter registration for 'object'. " + |
||||
"Check to ensure the Filter is only configured once."); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
verify(registration).addMappingForUrlPatterns(DEFAULT_DISPATCH, false, "/*"); |
||||
verify(context).addFilter(anyString(), eq(filter1)); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void onStartupWhenAppendFiltersEmptyThenException() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context); |
||||
} |
||||
}.onStartup(context)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("filters cannot be null or empty"); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenNullFilterAppendedThenException() { |
||||
Filter filter = mock(Filter.class); |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
|
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
when(context.addFilter(anyString(), eq(filter))).thenReturn(registration); |
||||
|
||||
assertThatCode(() -> |
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
protected void afterSpringSecurityFilterChain(ServletContext servletContext) { |
||||
appendFilters(context, filter, null); |
||||
} |
||||
}.onStartup(context)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("filters cannot contain null values"); |
||||
|
||||
verify(context, times(2)).addFilter(anyString(), any(Filter.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenDefaultsThenSessionTrackingModes() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
ArgumentCaptor<Set<SessionTrackingMode>> modesCaptor = ArgumentCaptor |
||||
.forClass(new HashSet<SessionTrackingMode>(){}.getClass()); |
||||
doNothing().when(context).setSessionTrackingModes(modesCaptor.capture()); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { }.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
Set<SessionTrackingMode> modes = modesCaptor.getValue(); |
||||
assertThat(modes).hasSize(1); |
||||
assertThat(modes).containsExactly(SessionTrackingMode.COOKIE); |
||||
} |
||||
|
||||
@Test |
||||
public void onStartupWhenSessionTrackingModesConfiguredThenUsed() { |
||||
ServletContext context = mock(ServletContext.class); |
||||
FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class); |
||||
|
||||
ArgumentCaptor<DelegatingFilterProxy> proxyCaptor = ArgumentCaptor.forClass(DelegatingFilterProxy.class); |
||||
when(context.addFilter(eq("springSecurityFilterChain"), proxyCaptor.capture())) |
||||
.thenReturn(registration); |
||||
|
||||
ArgumentCaptor<Set<SessionTrackingMode>> modesCaptor = ArgumentCaptor |
||||
.forClass(new HashSet<SessionTrackingMode>(){}.getClass()); |
||||
doNothing().when(context).setSessionTrackingModes(modesCaptor.capture()); |
||||
|
||||
new AbstractSecurityWebApplicationInitializer() { |
||||
@Override |
||||
public Set<SessionTrackingMode> getSessionTrackingModes() { |
||||
return Collections.singleton(SessionTrackingMode.SSL); |
||||
} |
||||
}.onStartup(context); |
||||
|
||||
assertProxyDefaults(proxyCaptor.getValue()); |
||||
|
||||
Set<SessionTrackingMode> modes = modesCaptor.getValue(); |
||||
assertThat(modes).hasSize(1); |
||||
assertThat(modes).containsExactly(SessionTrackingMode.SSL); |
||||
} |
||||
|
||||
@Test |
||||
public void defaultFilterNameEqualsSpringSecurityFilterChain() { |
||||
assertThat(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) |
||||
.isEqualTo("springSecurityFilterChain"); |
||||
} |
||||
|
||||
private static void verifyNoAddListener(ServletContext context) { |
||||
verify(context, times(0)).addListener(anyString()); |
||||
verify(context, times(0)).addListener(any(EventListener.class)); |
||||
verify(context, times(0)).addListener(any(Class.class)); |
||||
} |
||||
|
||||
private static void assertProxyDefaults(DelegatingFilterProxy proxy) { |
||||
assertThat(proxy.getContextAttribute()).isNull(); |
||||
assertThat(proxy).hasFieldOrPropertyWithValue("targetBeanName", "springSecurityFilterChain"); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue