springboot整合springsecurity从Hello World到源码解析(二):springsecurity配置加载解析
上一篇博客我们介绍了hellowrold入门,并且成功的看到了springsecurity的拦截效果,接下来我们就来看看springsecurity是如何做到的。
系列其它文章
[springboot整合springsecurity从Hello World到源码解析(一):hello world程序入门](https://blog.csdn.net/Iperishing/article/details/86504847)
[springboot整合springsecurity从Hello World到源码解析(二):springsecurity配置加载解析](https://blog.csdn.net/Iperishing/article/details/86505017)
[springboot整合springsecurity从Hello World到源码解析(三):基础配置详解](https://blog.csdn.net/Iperishing/article/details/86505120)
[springboot整合springsecurity从Hello World到源码解析(四):springsecurity基础架构解析](https://blog.csdn.net/Iperishing/article/details/86521621)
[springboot整合springsecurity从Hello World到源码解析(五):springsecurity+jwt整合restful服务](https://blog.csdn.net/Iperishing/article/details/86575416)
启动配置详解
我们知道(不知道的就当知道吧,哈哈),springboot启动时会帮我自动配置好很多的默认配置项,并且加载配置类都会写在spring.factories文件中,所以我们这里开始,看看springsecurity做了
那些配置,打开idea,ctrl+shift+n * 2,查找spring.factories文件:如下:
spring.factories
随后在该配置文件中,查找security,如下:
security
我们可以看到,一共初始化了9个security相关的类,这里我们不关注oauth2(以后再说)和reactive(springboot2以后新特性),还有
SecurityAutoConfiguration, SecurityRequestMatcherProviderAutoConfiguration, SecurityFilterAutoConfiguration, UserDetailsServiceAutoConfiguration这四个类,首先我们看下
SecurityAutoConfiguration:
1@Configuration
2@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
3@EnableConfigurationProperties(SecurityProperties.class)
4@Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class,
5 SecurityDataConfiguration.class })
6public class SecurityAutoConfiguration {
7
8 @Bean
9 @ConditionalOnMissingBean(AuthenticationEventPublisher.class)
10 public DefaultAuthenticationEventPublisher authenticationEventPublisher(
11 ApplicationEventPublisher publisher) {
12 return new DefaultAuthenticationEventPublisher(publisher);
13 }
14
15}
-
1.可以看出,这个类初始化了DefaultAuthenticationEventPublisher,看名字就知道,一个事件发布器,其内部实现就是spring的ApplicationEventPublisher,
用于springsecurity各种权限时间的交互,如登陆失败,会发布一个事件,然后通知其它组件做出相应的响应。 -
2.导入了一个配置类,SecurityProperties,如下:
1private String name = "user";
2
3private String password = UUID.randomUUID().toString();
4
5private List<String> roles = new ArrayList<>();
6
7private boolean passwordGenerated = true;
现在我们知道,我们上一篇博客中yml文件中配置的用户名密码就是这这里的配置,如果不进行配置,默认生成一个uuid的密码,从控制台可以看到该密码。
- 3.另外导入了三个配置项
SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class, SecurityDataConfiguration.class
其中data相关的因为此处我们没有导入spring-data相关的引用,不生效。
然后我们继续观察 WebSecurityEnablerConfiguration.class,看名字我们知道这是web环境下的初始化的配置,如下:
1@Configuration
2@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
3@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
4@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
5@EnableWebSecurity
6public class WebSecurityEnablerConfiguration {
7
8}
主要作用帮我们加入了 @EnableWebSecurity注解,该注解的作用为开启springsecurity httpsecurity的自定义配置,即我们可以自己定义web环境的url配置(后面的主要关注点)。
接下来就是@SpringBootWebSecurityConfiguration,如下:
1@Configuration
2@ConditionalOnClass(WebSecurityConfigurerAdapter.class)
3@ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class)
4@ConditionalOnWebApplication(type = Type.SERVLET)
5public class SpringBootWebSecurityConfiguration {
6
7 @Configuration
8 @Order(SecurityProperties.BASIC_AUTH_ORDER)
9 static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {
10
11 }
12
13}
关键点来了,这个配置项检查了servlet环境下spring容器中是否有WebSecurityConfiguraerAdapter这个bean,如果没有,就帮我们默认初始化了一个。所以我们对于springsecurity
的配置就要继承WebSecurityConfigurerAdapter,然后实现自定义的配置。
以上就是SecurityAutoConfiguration该配置项的作用,接下来我们看下SecurityRequestMatcherProviderAutoConfiguration
SecurityRequestMatcherProviderAutoConfiguration
1@Configuration
2@ConditionalOnClass({ RequestMatcher.class })
3@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
4public class SecurityRequestMatcherProviderAutoConfiguration {
5
6 @Configuration
7 @ConditionalOnClass(DispatcherServlet.class)
8 @ConditionalOnBean(HandlerMappingIntrospector.class)
9 public static class MvcRequestMatcherConfiguration {
10
11 @Bean
12 @ConditionalOnClass(DispatcherServlet.class)
13 public RequestMatcherProvider requestMatcherProvider(
14 HandlerMappingIntrospector introspector) {
15 return new MvcRequestMatcherProvider(introspector);
16 }
17
18 }
19
20 @Configuration
21 @ConditionalOnClass(ResourceConfig.class)
22 @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
23 @ConditionalOnBean(JerseyApplicationPath.class)
24 public static class JerseyRequestMatcherConfiguration {
25
26 @Bean
27 public RequestMatcherProvider requestMatcherProvider(
28 JerseyApplicationPath appl