在Spring Security 5.7及之后的版本中WebSecurityConfigurerAdapter
将被启用,安全框架将转向基于组件的安全配置。
Spring Security without the WebSecurityConfigurerAdapter
如果使用的Spring Boot版本高于低于2.7.0、Spring Security版本高于5.7,就会出现如下的提示:
1、被启用的原因是官方推荐开发正使用组件的(component-based)的安全配置。Spring的IOC容器可以管理一切Bean,Spring boot也是基于自动配置的,要实现某个功能还需要实现继承配置类,实现配置类的方法再DL注入到IOC中,这样显然是不方便的。
2、在组件化配置中,需要实现某些功能直接生产一一个该类型的Bean通过@Bean注解注入到IOC容器,覆盖spring boot默认配置,这种方式更加方便不用实现接口在重写方法,还能尽可能的减少配置类的数量。
在了解组件化配置时首先需要了解Spring Security - Lambda DSL,该工程是释放包括对DSL的增强,允许使用lambda配置HTTP安全性。
在Lambda DSL中,不需要使用 .及()方法。该 HTTP安全性实例在调用lambda方法后自动返回以进行进一步配置。lambda表达式it ->{}
的快捷方式。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers("/blog/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(formLogin ->
formLogin
.loginPage("/login")
.permitAll()
)
.rememberMe(withDefaults());
}
}
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/blog/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.rememberMe();
}
}
这样的好处是是配置更具有可读性,不需要再使用.and()
返回初始对象再重新配置规则。Spring Security - Lambda DSL
如果读者仍然习惯于WebSecurityConfigurerAdapter
的开发,也可以实现其父接口WebSecurityConfigurer
,不过还是推荐组件化配置。
在Spring Security主要实现了两个个功能,身份认证,权限认证。在最新的组件化配置中两个功能都可以通过组件化配置完成。对应的组件类型分别是UserDetailsService
,PasswordEncoder
,SecurityFilterChain
。
SecurityFilterChain
这个新的类的作用是代替了WebSecurityConfigurerAdapter
的configure
方法,因此不需要再去实现WebSecurityConfigurerAdapter类后再重写方法了,直接生产一个SecurityFilterChain
的实例即可。
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
return http.build();
}
}
配置也可旧版本的HttpSecurity
配置一致,也支持Spring Security - Lambda DSL
,小编还是熟悉.and()
的过滤器链的配置方式,接下来也会以该方式演示。
组件化配置过滤器链:
@Configuration
public class WebSecurityConfig {
//用户认证
@Bean(name = "userDetailsService")
UserDetailsService getUserService(){
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
return new User("admin",new BCryptPasswordEncoder().encode("123"),auths);
}
};
}
//过滤器链配置
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
//会话状态代理接口
.loginProcessingUrl("/doLogin")
.successForwardUrl("/index")
.permitAll()
.and()
.csrf().disable();
return http.build();
}
//密码加密
@Bean(name = "passwordEncoder")
PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
}
SecurityFilterChain
组件需要返回一个该类型的实例,在旧版本的配置中是无返回值的,如下
在SecurityFilterChain
组件中式有返回值的且返回值为HttpSecurity.build()
类型,该类型肯定是前者的实现类了,如下,提供了三个方法返回实现类:
三个方法都是用来实现过滤器链的,小编还不清楚它们的关系哈,再去看看源码,这里使用build方法就可以实现功能了。
在WebSecurityConfigurerAdapter接口中还有众多的方法,如下:
在新的组件化配置中都有对应的实现方案,如WebSecurityCustomizer
替代void configure(WebSecurity web)
方法。
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}
更多细节请移步官方文档Spring Security without the WebSecurityConfigurerAdapter