Allow security filter's dispatcher types to be configured via env
This commit adds a new property, security.filter-dispatcher-types that can be used to configure the dispatcher types of Spring Security's filter chain. The default remains unchanged. Closes gh-4505
This commit is contained in:
		
							parent
							
								
									8e0d3ed0eb
								
							
						
					
					
						commit
						524a32879f
					
				| 
						 | 
				
			
			@ -54,6 +54,7 @@ public class SecurityFilterAutoConfiguration {
 | 
			
		|||
		DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
 | 
			
		||||
				DEFAULT_FILTER_NAME);
 | 
			
		||||
		registration.setOrder(securityProperties.getFilterOrder());
 | 
			
		||||
		registration.setDispatcherTypes(securityProperties.getFilterDispatcherTypes());
 | 
			
		||||
		return registration;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,9 +18,12 @@ package org.springframework.boot.autoconfigure.security;
 | 
			
		|||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.DispatcherType;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.context.embedded.FilterRegistrationBean;
 | 
			
		||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
			
		||||
import org.springframework.core.Ordered;
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +36,7 @@ import org.springframework.util.StringUtils;
 | 
			
		|||
 * @author Dave Syer
 | 
			
		||||
 * @author Andy Wilkinson
 | 
			
		||||
 */
 | 
			
		||||
@ConfigurationProperties(prefix = "security")
 | 
			
		||||
@ConfigurationProperties(prefix = "security", ignoreUnknownFields = false)
 | 
			
		||||
public class SecurityProperties implements SecurityPrerequisite {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +101,11 @@ public class SecurityProperties implements SecurityPrerequisite {
 | 
			
		|||
	 */
 | 
			
		||||
	private int filterOrder = DEFAULT_FILTER_ORDER;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Security filter chain dispatcher types.
 | 
			
		||||
	 */
 | 
			
		||||
	private EnumSet<DispatcherType> filterDispatcherTypes;
 | 
			
		||||
 | 
			
		||||
	public Headers getHeaders() {
 | 
			
		||||
		return this.headers;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -154,6 +162,14 @@ public class SecurityProperties implements SecurityPrerequisite {
 | 
			
		|||
		this.filterOrder = filterOrder;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public EnumSet<DispatcherType> getFilterDispatcherTypes() {
 | 
			
		||||
		return this.filterDispatcherTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setFilterDispatcherTypes(EnumSet<DispatcherType> filterDispatcherTypes) {
 | 
			
		||||
		this.filterDispatcherTypes = filterDispatcherTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static class Headers {
 | 
			
		||||
 | 
			
		||||
		public enum HSTS {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,10 @@
 | 
			
		|||
 | 
			
		||||
package org.springframework.boot.autoconfigure.security;
 | 
			
		||||
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.DispatcherType;
 | 
			
		||||
 | 
			
		||||
import org.junit.After;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,11 +58,15 @@ import org.springframework.security.core.authority.AuthorityUtils;
 | 
			
		|||
import org.springframework.security.core.userdetails.UserDetailsService;
 | 
			
		||||
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
 | 
			
		||||
import org.springframework.security.web.FilterChainProxy;
 | 
			
		||||
import org.springframework.test.util.ReflectionTestUtils;
 | 
			
		||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 | 
			
		||||
 | 
			
		||||
import static org.hamcrest.Matchers.is;
 | 
			
		||||
import static org.hamcrest.Matchers.nullValue;
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertFalse;
 | 
			
		||||
import static org.junit.Assert.assertNotNull;
 | 
			
		||||
import static org.junit.Assert.assertThat;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
import static org.junit.Assert.fail;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +75,7 @@ import static org.junit.Assert.fail;
 | 
			
		|||
 *
 | 
			
		||||
 * @author Dave Syer
 | 
			
		||||
 * @author Rob Winch
 | 
			
		||||
 * @author Andy Wilkinson
 | 
			
		||||
 */
 | 
			
		||||
public class SecurityAutoConfigurationTests {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -360,6 +369,45 @@ public class SecurityAutoConfigurationTests {
 | 
			
		|||
		assertNotNull(this.context.getBean(SecurityEvaluationContextExtension.class));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void defaultFilterDispatcherTypes() {
 | 
			
		||||
		this.context = new AnnotationConfigWebApplicationContext();
 | 
			
		||||
		this.context.setServletContext(new MockServletContext());
 | 
			
		||||
		this.context.register(SecurityAutoConfiguration.class,
 | 
			
		||||
				SecurityFilterAutoConfiguration.class,
 | 
			
		||||
				ServerPropertiesAutoConfiguration.class,
 | 
			
		||||
				PropertyPlaceholderAutoConfiguration.class);
 | 
			
		||||
		this.context.refresh();
 | 
			
		||||
		DelegatingFilterProxyRegistrationBean bean = this.context.getBean(
 | 
			
		||||
				"securityFilterChainRegistration",
 | 
			
		||||
				DelegatingFilterProxyRegistrationBean.class);
 | 
			
		||||
		@SuppressWarnings("unchecked")
 | 
			
		||||
		EnumSet<DispatcherType> dispatcherTypes = (EnumSet<DispatcherType>) ReflectionTestUtils
 | 
			
		||||
				.getField(bean, "dispatcherTypes");
 | 
			
		||||
		assertThat(dispatcherTypes, is(nullValue()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void customFilterDispatcherTypes() {
 | 
			
		||||
		this.context = new AnnotationConfigWebApplicationContext();
 | 
			
		||||
		this.context.setServletContext(new MockServletContext());
 | 
			
		||||
		this.context.register(SecurityAutoConfiguration.class,
 | 
			
		||||
				SecurityFilterAutoConfiguration.class,
 | 
			
		||||
				ServerPropertiesAutoConfiguration.class,
 | 
			
		||||
				PropertyPlaceholderAutoConfiguration.class);
 | 
			
		||||
		EnvironmentTestUtils.addEnvironment(this.context,
 | 
			
		||||
				"security.filter-dispatcher-types:INCLUDE,ERROR");
 | 
			
		||||
		this.context.refresh();
 | 
			
		||||
		DelegatingFilterProxyRegistrationBean bean = this.context.getBean(
 | 
			
		||||
				"securityFilterChainRegistration",
 | 
			
		||||
				DelegatingFilterProxyRegistrationBean.class);
 | 
			
		||||
		@SuppressWarnings("unchecked")
 | 
			
		||||
		EnumSet<DispatcherType> dispatcherTypes = (EnumSet<DispatcherType>) ReflectionTestUtils
 | 
			
		||||
				.getField(bean, "dispatcherTypes");
 | 
			
		||||
		assertThat(dispatcherTypes,
 | 
			
		||||
				is(EnumSet.of(DispatcherType.INCLUDE, DispatcherType.ERROR)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static final class AuthenticationListener
 | 
			
		||||
			implements ApplicationListener<AbstractAuthenticationEvent> {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -390,6 +390,7 @@ content into your application; rather pick only the properties that you need.
 | 
			
		|||
	security.basic.realm=Spring # HTTP basic realm name.
 | 
			
		||||
	security.enable-csrf=false # Enable Cross Site Request Forgery support.
 | 
			
		||||
	security.filter-order=0 # Security filter chain order.
 | 
			
		||||
	security.filter-dispatcher-types=ASYNC, FORWARD, INCLUDE, REQUEST # Security filter chain dispatcher types.
 | 
			
		||||
	security.headers.cache=true # Enable cache control HTTP headers.
 | 
			
		||||
	security.headers.content-type=true # Enable "X-Content-Type-Options" header.
 | 
			
		||||
	security.headers.frame=true # Enable "X-Frame-Options" header.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue