上一篇文章我们解析了SecurityAutoConfiguration
,此篇幅将介绍第二个配置SecurityFilterAutoConfiguration
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SecurityProperties.class)
@ConditionalOnClass({ AbstractSecurityWebApplicationInitializer.class,
SessionCreationPolicy.class })
//此配置类在SecurityAutoConfiguration 这个配置之后才进行配置,具有前后依赖关系
@AutoConfigureAfter(SecurityAutoConfiguration.class)
public class SecurityFilterAutoConfiguration {
private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;
//此处仅创建一个DelegatingFilterProxyRegistration
//用于容纳将上一步创建的securityFilterChain,并交给sevlet的原生Filter管理
//此处可以对securityFilterChain 在Filter中的位置进行配置。
@Bean
@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
SecurityProperties securityProperties) {
DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
DEFAULT_FILTER_NAME);
registration.setOrder(securityProperties.getFilter().getOrder());
registration.setDispatcherTypes(getDispatcherTypes(securityProperties));
return registration;
}
private EnumSet<DispatcherType> getDispatcherTypes(
SecurityProperties securityProperties) {
if (securityProperties.getFilter().getDispatcherTypes() == null) {
return null;
}
return securityProperties.getFilter().getDispatcherTypes().stream()
.map((type) -> DispatcherType.valueOf(type.name())).collect(Collectors
.collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}
}
DelegatingFilterProxyRegistrationBean
public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistrationBean<DelegatingFilterProxy> implements ApplicationContextAware {
private ApplicationContext applicationContext;
private final String targetBeanName;
//调用父类将传进来的securityFilterChain交给sevlet管理。
public DelegatingFilterProxyRegistrationBean(String targetBeanName, ServletRegistrationBean<?>... servletRegistrationBeans) {
super(servletRegistrationBeans);
Assert.hasLength(targetBeanName, "TargetBeanName must not be null or empty");
this.targetBeanName = targetBeanName;
this.setName(targetBeanName);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
protected String getTargetBeanName() {
return this.targetBeanName;
}
public DelegatingFilterProxy getFilter() {
return new DelegatingFilterProxy(this.targetBeanName, this.getWebApplicationContext()) {
protected void initFilterBean() throws ServletException {
}
};
}
private WebApplicationContext getWebApplicationContext() {
Assert.notNull(this.applicationContext, "ApplicationContext be injected");
Assert.isInstanceOf(WebApplicationContext.class, this.applicationContext);
return (WebApplicationContext)this.applicationContext;
}
}