关于java:Spring-Security-实战干货54版本带来的新玩法

7次阅读

共计 2225 个字符,预计需要花费 6 分钟才能阅读完成。

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. 新的配置形式

旧的配置形式 目前仍然无效

@Configuration
static class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/**")
            .authorizeRequests(authorize -> authorize
                    .anyRequest().authenticated()
            );
    }
}

不过 5.4.x 版本咱们有新的抉择:

@Bean
SecurityFilterChain 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

正文完
 0