如何理解学习SpringSecurity的自动配置原理以及其拓展——举例进行学习——从0到1教会方法自行学习

📑本篇内容:如何理解学习SpringSecurity的自动配置原理以及其拓展——举例进行学习——从0到1教会方法自行学习

📘 文章专栏:前后端分离项目(Vue + SpringBoot)

🎬最近更新:2022年2月16日 SpringSecurity如何理解学习常用拦截器——举例进行学习——从0到1教会方法自行学习~

🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)

🌇点赞 👍 收藏 ⭐留言 📝 一键三连 关爱程序猿,从你我做起

📝SpringSecurity在SpringBoot中的自动装配原理

⭐SpringBoot的自动装配原理⭐

如果不知道SpringBoot的自动装配原理可以看这里哦~

小付总结的SpringBoot自动装配原理:

SpringBoot的自动装配原理——其实真得就是你想的那么简单

这里简单提一下:其实SpringBoot在整合所有的Spring全家桶时都采用了对应的自动装配配置,那这些自动配置是交给了哪些呢?

读过源码的同学们都知道,在AutoConfigurationImportSelector 类中的一个方法通过调用了SpringFactoriesLoader类中的静态方法loadSpringFactories(ClassLoader classLoader)来加载的自动配置类。

Enumeration urls = classLoader.getResources("META-INF/spring.factories");

所以由此我们可以得知所有的自动配置类都是存在于 spring-boot-autoconfigure-2.6.3.jar!\META-INF\spring.factories中的。

既然我们要分析SpringBoot对于SpringSecurity的自动配置只需要在对应的factories中找到对应的配置类进行分析就好了。

⭐SecurityAutoConfiguration⭐

在对应的spring.factories文件中我们找到了配置SpringSecurity的自动配置类——SecurityAutoConfiguration。如图所示:

在这里插入图片描述

SecurityAutoConfiguration.java源码分析

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
@EnableConfigurationProperties(SecurityProperties.class)
@Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class,
		SecurityDataConfiguration.class, ErrorPageSecurityFilterConfiguration.class })
public class SecurityAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
	public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher publisher) {
		return new DefaultAuthenticationEventPublisher(publisher);
	}

}

又到了烦人的读源码环节了,这里小付以配置SpringSecurity扩展来进行举例说明,为什么当我们配置了一个扩展Security配置类需要继承 WebSecurityConfigurerAdapter来理解

  • @Configuration(proxyBeanMethods = false) :说明该类会作为一个配置类的组件注入到Spring容器当中 ,并且不会生成对应的代理。
  • @ConditionalOnClass(DefaultAuthenticationEventPublisher.class): 该配置类是依赖于 DefaultAuthenticationEventPublisher.class的,如果Spring容器当中没有对应的类,则该类不会被注入。
  • @EnableConfigurationProperties(SecurityProperties.class): 支持对应的配置文件,咱们可以通过在application.yaml文件中配置这个 SecurityProperties 类中的属性,实行部分简单的客制化配置。
  • @Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class, SecurityDataConfiguration.class, ErrorPageSecurityFilterConfiguration.class }) : 引入所需要的部分类。

⭐SpringBootWebSecurityConfiguration⭐

既然上述导入的第一个类是SpringBootWebSecurityConfiguration,字如其意:这是有关于SpringBoot与Security 在Web应用上的相关配置类。

咱们可以看看它的源码:

SpringBootWebSecurityConfiguration.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {

	@Bean
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
		return http.build();
	}

}

其他的注解咱们都见过,唯独这个 @ConditionalOnDefaultWebSecurity 我们是第一次见,等会儿咱们就跟着分析这个注解,先看到这个作为配置类,干了啥,将什么东西注册到我们的Spring容器当中了SecurityFilterChain这个安全过滤器链,了解过SpringSecurity的architecture (架构)的同学们应该知道这玩意在SpringSecurity中起到的作用了。

这里用官方的图来进行理解一下:

在这里插入图片描述

小付简单总结一下这个玩意在框架架构中干了啥: 众所周知,当用户需要访问咱们的Web应用程序之前都会经过过滤器或者是拦截器,进行请求过滤或拦截等操作,SpringSecurity就是基于过滤请求链来实现的安全框架,这就不得不提到了过滤器链这个名词,在官网也讲述了,SpringSecurity一共自行构建了大概30个被叫做SpringSecurityFilter而在Java类中被叫做FilterSecurityInterceptor类的过滤器,这些被应用到默认开启的15个过滤器构成一条过滤器链——SecurityFilterChain,此时我们获得得到了一条SecurityFilterChain ,那我们如何将其整合到我们的原生FilterChain上呢?不用担心,Spring官方框架中有一个专门用于整合Spring框架中的过滤器到咱们的web上过滤器链的代理类——DelegatingFilterProxy,这个代理类代理的是由Spring框架整合由继承GenericFilterBean这个抽象类的SpringFilter们,但是SecurityFilterChain是无法直接交给DelegatingFilterProxy进行代理的,因为SecurityFilterChain并没有继承GenericFilterBean这个抽象类,也没有实现他的对应方法,所以就无法直接进行整合,那么这里就有需要代理到DelegatingFilterProxy中去,Spring也想到了这个问题,所以就有了Security框架中新构建的FilterChainProxy类去进行代理咱们的SecurityFilterChainDelegatingFilterProxy,然后DelegatingFilterProxy代理到咱们的web应用上的过滤器链。


以上就是SecurityFilterChain被注册到咱们的Spring容器中了,并且针对于HttpSecurity http的请求也进行了拦截器的对应拦截,这里不再细讲,有兴趣的可以去看看封装的HttpSecurity=-=小付表示这辈子不可能看第二遍了。只需要记住这个封装的http做了很多配置Security的操作,例如对请求的访问身份认证授权跳转登录/错误页面等的相关配置,后面会扩展的时候用到。

⭐@ConditionalOnDefaultWebSecurity⭐

好了咱们言归正传吧:该来讲下咱们不认识的这个注解了。

@ConditionalOnDefaultWebSecurity 源码分析

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(DefaultWebSecurityCondition.class)
public @interface ConditionalOnDefaultWebSecurity {

}

除了元注解之外,@Conditional注解标注了这个注解是依赖于DefaultWebSecurityCondition类进行运行的。既然如此咱们就需要到里面一探究竟,到底是为何?

DefaultWebSecurityCondition.java

class DefaultWebSecurityCondition extends AllNestedConditions {

	DefaultWebSecurityCondition() {
		super(ConfigurationPhase.REGISTER_BEAN);
	}

	@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
	static class Classes {

	}

	@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
	static class Beans {

	}

}
  • 看到源码你知道了为什么当我们在继承WebSecurityConfigurerAdapter就会对原有的SpringSecurity进行扩展配置了吧
  • 因为@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })这个注解已经告诉我们了,当我们的Spring容器中含有了WebSecurityConfigurerAdapter类及其子类时
  • 那么这个默认的DefaultWebSecurityCondition将不会进行配置了。所以这也就是为什么我们对SpringSecurity进行扩展的时候,需要继承这个类来达成自定义配置的设置了。

🙊总结

其实关于所有的SpringBoot整合框架的学习都可以从此入手只要能看懂部分注解,看懂代码逻辑关系,就可以自行学习官方文档啦,但是这个时间是比较漫长的,肯定比不上人家视频教学那种,自己学了总结的知识吐出来那样,但是归结一点,学会了方法,这对于以后任何新出的框架学习都轻松上手,而不是一直吃别人吐出来的qwq,学会了就是自己的了,自学一遍收货可能会更多,今天是因为刚好把昨天整理的内容一起发出来了,就顺便将就一下~有一点点难理解,但是小付总结了简明扼要的语言去描述这个该如何理解,就酱紫吧,今天还是项目整合SpringSecurity的一天。

在这里插入图片描述

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alascanfu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值