引言:

事情是这样的,我最近打算学习了springSecurity的时候,跟着视频学习的时候发现配置类 WebSecurityConfigurerAdapter 过时了,这个问题本篇的文章会告诉你答案,以及我有不小心选择了spring boot3.0 的版本然后authorizeRequests也过时了。如果此文章有错欢迎大佬批评指教。

Spring-Security的版本

Spring-Security5.7+版本

这个版本差不多是spring-boot 2.7版本使用的,首先WebSecurityConfigurerAdapter 过时,但是在在过时的源码类中,会叫我们如何进行配置新版本的Spring-Security的配置,官方的我贴这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
提供用于创建 WebSecurityConfigurer 实例的方便基类。该实现允许通过重写方法进行自定义。
将自动应用查找 AbstractHttpConfigurer 自 SpringFactoriesLoader 的结果,以允许开发人员扩展默认值。
为此,您必须创建一个扩展 AbstractHttpConfigurer 的类,
然后在“META-INF/spring.factory”的类路径中创建一个文件,如下所示:
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer=
sample.MyClassThatExtendsAbstractHttpConfigurer
如果有多个应添加的类,则可以使用 “,”分隔值。例如:
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer=
sample.MyClassThatExtendsAbstractHttpConfigurer, sample.OtherThatExtendsAbstractHttpConfigurer
已弃用
org.springframework.security.web.SecurityFilterChain使用
Bean 进行配置或WebSecurityCustomizer使用 Bean 进行配置 HttpSecurity WebSecurity。
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) ->
authz.anyRequest().authenticated()
);
// ...
return http.build();
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer(WebSecurity web) {
return (web) -> web.ignoring().antMatchers("/resources/**");
}
/**
请参阅 Spring Security without WebSecurityConfigurerAdapter 以获取更多详细信息。
请参阅:
EnableWebSecurity
作者:
罗伯·温奇
*/

可以看到,新版本官方推荐使用@Bean 进行配置,这个感觉更加优雅了,和我们原来使用配置类进行配置的都是大同小异,但这里有个问题官方没有讲(或许我没有找到)。

关于 AuthenticationManager 认证类的问题

因为,可能我们需要因为某种原因重写 过滤器的类,但最后我们在旧版本需要指定一个AuthenticationManager 类不管是工厂里的还是直接springboot启动时创建的。这个地方我查了好久网上的没有一个能一个找到的,全部都是重复。

1
2
3
4
5
6
7
8
@Autowired
AuthenticationConfiguration authenticationConfiguration;

public AuthenticationManager authenticationManager() throws Exception {
AuthenticationManager authenticationManager =
authenticationConfiguration.getAuthenticationManager();
return authenticationManager;
}

我们只需要使用 AuthenticationConfiguration 创建一个``AuthenticationManager 类即可,推荐写在Security配置类中,这样可以直接方便调用即可。

例如我重写了 UsernamePasswordAuthenticationFilter的过滤器 KaptchaFilter 是继承了UsernamePasswordAuthenticationFilter 和并且重写了里面的方法加入了验证码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Bean
public KaptchaFilter kaptchaFilter() throws Exception {
KaptchaFilter kaptchaFilter = new KaptchaFilter();
kaptchaFilter.setFilterProcessesUrl("/doLogin");
kaptchaFilter.setUsernameParameter("uname");
kaptchaFilter.setPasswordParameter("passwd");
kaptchaFilter.setKaptcha("kaptcha");
//指定认证管理器
kaptchaFilter.setAuthenticationManager(authenticationManager());
kaptchaFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
response.sendRedirect("/index.html");
});
kaptchaFilter.setAuthenticationFailureHandler((request, response, exception) -> {
response.sendRedirect("/login.html");
});
return kaptchaFilter;
}

@Bean
public SecurityFilterChain securityFilter(HttpSecurity http)throws Exception{
return http.authorizeRequests()
.mvcMatchers("/login.html").permitAll()
.mvcMatchers("/vc.jpg").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("uname")
.passwordParameter("passwd")
.defaultSuccessUrl("/index.html",true)
.and()
.csrf().disable()
.addFilterAt(kaptchaFilter(), UsernamePasswordAuthenticationFilter.class)
.build();


}

关于SpringSecurity6.02+版本

这个版本差不多是spring boot 3.0+开始使用的,如果你按照上面新版本使用@Bean配置的话,会发现HttpSecurity中的authorizeRequests 方法标记为过时了,而且mvcMatchers也没有这个方法了,原因6.0的SpringSecurity推荐使用authorizeHttpRequests进行配置,对就是很烦人,不能一个版本改完,而且文档及其混乱。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests()
.requestMatchers("/vc.jpg").permitAll()//放行指定选项
.anyRequest().authenticated()//拦截所有请求都需要认证
.and()
.formLogin()
.and()
.logout()
.and()
.addFilterAt(loginKaptchaFilter(),UsernamePasswordAuthenticationFilter.class)
.csrf().disable()
.build();

}

其他配置和SpringSecurity5.7+的配置一样。