在springboot体系下我们一般是找 xxxAutoConfiguration,那么这里我们可以通过查找securityAutoConfiguration可以找到如下类:
SecurityAutoConfiguration
SecurityFilterAutoConfiguration
SecurityRequestMatcherProviderAutoConfiguration
ManagementWebSecurityAutoConfiguration
MockMvcSecurityAutoConfiguration
ReactiveManagementWebSecurityAutoConfiguration
ReactiveSecurityAutoConfiguration
这些类都是在springboot-autoconfig 包下面,即我们一旦引入spring-security的相关包时将初始化加载以上的一些配置。
SecurityAutoConfiguration
@Configuration
//当引入了spring-security-core包时即自动启用该类
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
//启用配置
@EnableConfigurationProperties(SecurityProperties.class)
//导入以下几个类,我们知道import即加载实例化类到ioc容器
@Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class,
SecurityDataConfiguration.class })
public class SecurityAutoConfiguration {
//实例化认证事件发布器
@Bean
@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
public DefaultAuthenticationEventPublisher authenticationEventPublisher(
ApplicationEventPublisher publisher) {
return new DefaultAuthenticationEventPublisher(publisher);
}
}
接着我们来看这三个类
SpringBootWebSecurityConfiguration
WebSecurityEnablerConfiguration
SecurityDataConfiguration
SpringBootWebSecurityConfiguration
@Configuration
@ConditionalOnClass(WebSecurityConfigurerAdapter.class)
@ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
public class SpringBootWebSecurityConfiguration {
//配置一个空的 WebSecurityConfigurerAdapter 静态子类实际没做什么操作
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER)
static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {
}
}
WebSecurityEnablerConfiguration
@Configuration
@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
//最重要的是这个注解
@EnableWebSecurity
public class WebSecurityEnablerConfiguration {
}
我们看这个注解@EnableWebSecurity
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = { java.lang.annotation.ElementType.TYPE })
@Documented
//这里又导入了三个配置类
@Import({ WebSecurityConfiguration.class,
//这两个类的作用大家如果不了解可以去看ImportSelector相关文章这里不多介绍
SpringWebMvcImportSelector.class,
OAuth2ImportSelector.class })
//此处启用了这个配置实际导入了AuthenticationConfiguration此类
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
//可以给注解配置一个debug属性用于调试
boolean debug() default false;
}
SecurityDataConfiguration
此类纯粹只是为了整合spring-data模块使用。这里暂不解释
接着我们来看@EableWebSecurity中导入的类
WebSecurityConfiguration
SpringWebMvcImportSelector
OAuth2ImportSelector
AuthenticationConfiguration
上面的系类步骤就为了此处服务,我们先来看一张官方图再来看这个类
WebSecurityConfiguration
@Configuration
//此处实现了importAware以及BeanClassLoaderAware两个接口,在springIOC中
//相当于赋予当前类拥有这两个类的能力
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
private WebSecurity webSecurity;
//从注解中获得的debug属性
private Boolean debugEnabled;
//安全配置容器
private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers;
//由父类接口提供的能力
private ClassLoader beanClassLoader;
@Autowired(required = false)
private ObjectPostProcessor<Object> objectObjectPostProcessor;
//实例化一个委托应用监听器
@Bean
public static DelegatingApplicationListener delegatingApplicationListener() {
return new DelegatingApplicationListener();
}
//实例化security表达式处理器
@Bean
@DependsOn(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public SecurityExpressionHandler<FilterInvocation> webSecurityExpressionHandler() {
return webSecurity.getExpressionHandler();
}
// 通过webSecurity build 构造出 Spring Security Filter Chain
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
boolean hasConfigurers = webSecurityConfigurers != null
&& !webSecurityConfigurers.isEmpty();
if (!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
.postProcess(new WebSecurityConfigurerAdapter() {
});
webSecurity.apply(adapter);
}
return webSecurity.build();
}
//创建一个web调用评估器
@Bean
@DependsOn(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public WebInvocationPrivilegeEvaluator privilegeEvaluator() throws Exception {
return webSecurity.getPrivilegeEvaluator();
}
//从springioc容器获取所有的securityConfigure并缓存到当前webSecurityConfigurers容器中备用。
@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(
ObjectPostProcessor<Object> objectPostProcessor,
@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
throws Exception {
webSecurity = objectPostProcessor
.postProcess(new WebSecurity(objectPostProcessor));
if (debugEnabled != null) {
webSecurity.debug(debugEnabled);
}
Collections.sort(webSecurityConfigurers, AnnotationAwareOrderComparator.INSTANCE);
Integer previousOrder = null;
Object previousConfig = null;
for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
if (previousOrder != null && previousOrder.equals(order)) {
throw new IllegalStateException(
"@Order on WebSecurityConfigurers must be unique. Order of "
+ order + " was already used on " + previousConfig + ", so it cannot be used on "
+ config + " too.");
}
previousOrder = order;
previousConfig = config;
}
for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
webSecurity.apply(webSecurityConfigurer);
}
this.webSecurityConfigurers = webSecurityConfigurers;
}
//实例化一个AutowiredWebSecurityConfigurersIgnoreParents对象用于获取所有配置类。
//上一个方法中注入此示例调用getWebSecurityConfigurers获取到的所有configure。
//并做了加载排序以及设置属性等操作。
@Bean
public static AutowiredWebSecurityConfigurersIgnoreParents autowiredWebSecurityConfigurersIgnoreParents(
ConfigurableListableBeanFactory beanFactory) {
return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
}
//获取所有ordered注解用于排序加载
private static class AnnotationAwareOrderComparator extends OrderComparator {
private static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator();
@Override
protected int getOrder(Object obj) {
return lookupOrder(obj);
}
private static int lookupOrder(Object obj) {
if (obj instanceof Ordered) {
return ((Ordered) obj).getOrder();
}
if (obj != null) {
Class<?> clazz = (obj instanceof Class ? (Class<?>) obj : obj.getClass());
Order order = AnnotationUtils.findAnnotation(clazz, Order.class);
if (order != null) {
return order.value();
}
}
return Ordered.LOWEST_PRECEDENCE;
}
}
//用于获取一些源数据,此处用于获取@EnableWebSecurity中的debug属性。
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> enableWebSecurityAttrMap = importMetadata
.getAnnotationAttributes(EnableWebSecurity.class.getName());
AnnotationAttributes enableWebSecurityAttrs = AnnotationAttributes
.fromMap(enableWebSecurityAttrMap);
debugEnabled = enableWebSecurityAttrs.getBoolean("debug");
if (webSecurity != null) {
webSecurity.debug(debugEnabled);
}
}
//父类功能提供类加载器
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
}
篇幅有限仅能介绍完一个接口,后续接口另起篇幅。