Spring 安全自定义过滤器(在 AuthenticationManager bean 已经存在时创建它的原因)

Posted

技术标签:

【中文标题】Spring 安全自定义过滤器(在 AuthenticationManager bean 已经存在时创建它的原因)【英文标题】:Spring security custom filter (reason for creating AuthenticationManager bean while it already exists) 【发布时间】:2021-12-09 19:42:05 【问题描述】:

当我们使用自定义过滤器时,我们需要注入 AuthenticationManager 类型的 bean。

据我所知,如果我们使用默认过滤器,那么 Spring 会自动提供身份验证管理器。这使我得出结论,在 Spring 上下文中已经有一个 AuthenticationManager bean(根据我的理解)。

但问题是我的假设不正确。我必须创建一个 AuthenticationManager 的 bean 并将其注入过滤器。

我的假设有什么问题?为什么我们需要在 bean 已经存在的时候将其打包?

【问题讨论】:

【参考方案1】:

Spring 使用AuthenticationManager 来查找合适的身份验证提供程序,但默认情况下没有将AuthenticationManager 注册为bean。查看HttpSecurityConfiguration类的源码。

@Bean(HTTPSECURITY_BEAN_NAME)
@Scope("prototype")
HttpSecurity httpSecurity() throws Exception 
    WebSecurityConfigurerAdapter.LazyPasswordEncoder passwordEncoder = new WebSecurityConfigurerAdapter.LazyPasswordEncoder(
            this.context);
    AuthenticationManagerBuilder authenticationBuilder = new WebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(
            this.objectPostProcessor, passwordEncoder);
    authenticationBuilder.parentAuthenticationManager(authenticationManager());
    HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
    // @formatter:off
    http
        .csrf(withDefaults())
        .addFilter(new WebAsyncManagerIntegrationFilter())
        .exceptionHandling(withDefaults())
        .headers(withDefaults())
        .sessionManagement(withDefaults())
        .securityContext(withDefaults())
        .requestCache(withDefaults())
        .anonymous(withDefaults())
        .servletApi(withDefaults())
        .apply(new DefaultLoginPageConfigurer<>());
    http.logout(withDefaults());
    // @formatter:on
    return http;


private AuthenticationManager authenticationManager() throws Exception 
    return (this.authenticationManager != null) ? this.authenticationManager
            : this.authenticationConfiguration.getAuthenticationManager();

如您所见,它在HttpSecurity 中注册了一个身份验证管理器构建器。稍后在HttpSecurity 类中,它将使用此构建器来构建身份验证管理器并将其注册到共享对象中[参见HttpSecurity 中的beforeConfigure() 方法]。

@Override
protected void beforeConfigure() throws Exception 
    setSharedObject(AuthenticationManager.class, getAuthenticationRegistry().build());

并且每当需要身份验证管理器时,它都会使用HttpSecurity 来获得它,如下所示:

AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);

【讨论】:

非常感谢。你是救生员。

以上是关于Spring 安全自定义过滤器(在 AuthenticationManager bean 已经存在时创建它的原因)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Security 为微服务创建自定义安全过滤器

多次调用 Spring 安全自定义过滤器

如何避免自定义过滤器在spring-security中为不安全的url运行

Spring Security 自定义过滤器被基本 http 安全覆盖

Spring 安全性和自定义 AuthenticationFilter 与 Spring boot

Spring Security 自定义身份验证过滤器和授权