spring-security 在Sping Boot 2.7中,Spring Security具有OAuth2,但不具有WebSecurityConfigurerAdapter,但没有AuthenticationEventPublisher

hkmswyz6  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(353)

我以前基于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的方法来返回SecurityFilterChainas 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)

91zkwejq

91zkwejq1#

看起来您关于默认值AuthenticationEventPublisher的假设并不正确。
实际上,缺省的一个(DefaultAuthenticationEventPublisher)是通过Spring Security自动配置提供的:org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration#authenticationEventPublisher() .
然后,AuthenticationConfiguration将获取该事件,并创建一个AuthenticationManagerBuilder,该AuthenticationManagerBuilder将根据请求创建上述ProviderManager,其中包含已填充的事件发布者。

相关问题