我以前基于Sping Boot 2.6的安全配置代码运行良好:
@Configuration @EnableWebSecurity
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
. . .
.and()
.oauth2ResourceServer()
.jwt();
}
}
我现在正在升级已弃用的WebSecurityConfigurerAdapter
类的用法,以支持使用@Bean
的方法来返回SecurityFilterChain
as recommended,并且我的应用程序不再具有有效的AuthenticationEventPublisher
:
@Configuration @EnableWebSecurity
public class ResourceServerConfig {
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
. . .
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
}
}
我的问题的原因是:对象BearerTokenAuthenticationFilter
使用ProviderManager
作为AuthenticationManager
(甚至在使用WebSecurityConfigurerAdapter
之前)。但默认情况下,ProviderManager
以如下方式声明其AuthenticationEventPublisher
:
public class ProviderManager implements AuthenticationManager, . . . {
. . .
private AuthenticationEventPublisher eventPublisher = new NullEventPublisher();
这就是问题所在:NullEventPublisher是不发布事件的空实现。
之前使用WebSecurityConfigurerAdapter
时-ProviderManager
的eventPublisher对象被分配了DefaultAuthenticationEventPublisher
对象
经过一些测试后,我能够使用以下代码“修复问题”:
@Configuration
@ConditionalOnClass({AuthenticationEventPublisher.class, JwtAuthenticationProvider.class})
public class SpringConfiguration { //global configuration for several others
@Bean
public ProviderManager providerManagerAvecDefaultAuthenticationPublisher(@Lazy JwtDecoder jwtDecoder, AuthenticationEventPublisher authenticationPublisher) {
JwtAuthenticationProvider authenticationProvider = new JwtAuthenticationProvider(jwtDecoder);
ProviderManager providerManager = new ProviderManager(Arrays.asList(authenticationProvider));
providerManager.setAuthenticationEventPublisher(authenticationPublisher);
return providerManager;
}
}
同时调整我的安全配置:
@Configuration @EnableWebSecurity
public class ResourceServerConfig {
@Autowired ProviderManager manager; //1
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
. . .
.and()
.oauth2ResourceServer()
.jwt()
.authenticationManager(manager); //2
return http.build();
}
}
但我有两个顾虑:
1.我的模块/应用程序的目的是供我公司的其他应用程序使用,以便发布特定的日志。
1.我没有意识到为这些应用程序“强制”预构建ProviderManager
的风险
最后我的问题是:是否有一种方法可以从ProviderManager
绕过eventPublisher = new NullEventPublisher()
,而不必在所有配置其SecurityFilterChain
的应用程序中强制配置oauth2ResourceServer().authenticationManager(manager)
?
1条答案
按热度按时间91zkwejq1#
看起来您关于默认值
AuthenticationEventPublisher
的假设并不正确。实际上,缺省的一个(
DefaultAuthenticationEventPublisher
)是通过Spring Security自动配置提供的:org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration#authenticationEventPublisher()
.然后,
AuthenticationConfiguration
将获取该事件,并创建一个AuthenticationManagerBuilder
,该AuthenticationManagerBuilder
将根据请求创建上述ProviderManager
,其中包含已填充的事件发布者。