1. 前言
在以往Spring Security的教程中咱们自定义配置都是申明一个配置类WebSecurityConfigurerAdapter
,而后覆写(@Override
)对应的几个办法就行了。然而这所有在Spring Security 5.4开始就失去了扭转,从Spring Security 5.4 起咱们不须要继承WebSecurityConfigurerAdapter
就能够配置HttpSecurity
了。相干的阐明原文:
- Remove need for WebSecurityConfigurerAdapter #8805
- Configure HTTP Security without extending WebSecurityConfigurerAdapter #8804
发稿时最新的Spring Security版本为 5.4.5。
2. 新的配置形式
旧的配置形式目前仍然无效:
@Configurationstatic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/**") .authorizeRequests(authorize -> authorize .anyRequest().authenticated() ); }}
不过5.4.x版本咱们有新的抉择:
@BeanSecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .antMatcher("/**") .authorizeRequests(authorize -> authorize .anyRequest().authenticated() ) .build();}
这种JavaConfig的形式看起来更加清新难受,而且和适配器解耦了。等等我如同发现了新的货色,下面filterChain
办法的参数是HttpSecurity
类型。相熟@Bean
注解的同学应该会意识到肯定有一个HttpSecurity
类型的Spring Bean。没错!就在HttpSecurityConfiguration
中有一个这样的Bean:
@Bean({"org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration.httpSecurity"})@Scope("prototype")HttpSecurity httpSecurity() throws Exception { // 省略掉 return http;}
初始化的内容曾经疏忽掉,它不是本文关注的重点。咱们留神到HttpSecurity
被@Scope("prototype")
标记。也就是这个HttpSecurity
Bean不是单例的,每一次申请都会结构一个新的实例。这个设定十分不便咱们构建多个相互没有太多关联的SecurityFilterChain
,进而能在一个平安体系中构建互相隔离的安全策略。比方后端治理平台用Session模式,前台利用端用Token模式。
3. 原理
Spring Security 有一个名为springSecurityFilterChain
默认的过滤器链类(理论地位就是上图的 Bean Filter地位),其类型为FilterChainProxy
, 它代理了所有的SecurityFilterChain
,要害的代理注入代码:
for (SecurityFilterChain securityFilterChain : this.securityFilterChains) { this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain); for (Filter filter : securityFilterChain.getFilters()) { if (filter instanceof FilterSecurityInterceptor) { this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter); break; } }}
那么this.securityFilterChains
来自哪里呢?
@Autowired(required = false)void setFilterChains(List<SecurityFilterChain> securityFilterChains) { securityFilterChains.sort(AnnotationAwareOrderComparator.INSTANCE); this.securityFilterChains = securityFilterChains;}
到这里就高深莫测了吧,SecurityFilterChain
类型的Bean会被加载到this.securityFilterChains
中。如果你的Spring Security 版本升级到 5.4.x**,就能够尝试一下这种形式。
关注公众号:Felordcn 获取更多资讯
集体博客:https://felord.cn