始终调用Spring自定义筛选器

时间:2017-10-05 22:49:31

标签: spring spring-mvc spring-boot spring-security

我有一个在BasicAuthenticationFilter之前调用的自定义过滤器,Bean在SecurityConfig文件中自动装配。

.addFilterBefore(preAuthTenantContextInitializerFilter, BasicAuthenticationFilter.class)

以下是过滤器的外观。

@Component
public class PreAuthTenantContextInitializerFilter extends OncePerRequestFilter {
    @Autowired
    private TenantService tenantService;
.....
.....

我希望此过滤器不会像其他Spring Security过滤器链那样触发WebSecurityConfigurerAdapter #configure(WebSecurity web)web.ignoring()中包含的路径。

以下是它的样子

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", 
                                    "/configuration/security", "/swagger-ui.html", 
                                    "/webjars/**","/swagger-resources/configuration/ui",
                                    "/swagge‌​r-ui.html", "/docs/**");
    }
}

我已尝试过的内容。

从过滤器类中删除@Component注释,它只会阻止过滤器在任何情况下调用,因为过滤器不再被选为bean并且永远不会进入过滤器链。

我在寻找什么

我希望在调用Spring Security链的其余部分时调用此过滤器,并在web.ignoring()中忽略其路径,就像其他Spring Security过滤器一样。感谢。

2 个答案:

答案 0 :(得分:5)

  

任何作为Spring bean的ServletFilterServlet *Listener实例都将在嵌入式容器中注册。如果您想在配置期间引用application.properties中的值,这可能会特别方便。

此代码段来自Spring Boot reference guide。基本上,在应用程序上下文中检测到的任何Filter都将注册到默认过滤器链并映射到DispatcherServlet/

在您的情况下,由于过滤器标记为@Component,它将是一个bean,Spring Boot检测到并将其注册到嵌入式容器中。但是,您不希望它只是您希望它成为Spring Security过滤器链的一部分。

为此,您有2个选项。

  1. 删除@Component@Autowired并构建您自己的实例,不要将其作为bean。
  2. 添加额外的[FilterRegistrationBean]并将enabled属性设置为false,这将阻止Spring Boot将其注册到嵌入式容器中。
  3. Herer是选项2的解决方案:

    @Bean
    public FilterRegistrationBean preAuthTenantContextInitializerFilterRegistration(PreAuthTenantContextInitializerFilter filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean(filter);
        registration.setEnabled(false);
        return registration;
    }
    

    使用这个添加的bean,Spring Boot不会在嵌入式容器中注册过滤器,因此它只会作为Spring Security过滤器链的一部分进行调用。

答案 1 :(得分:1)

  • 我认为你试图忽略加载Swagger UI页面的安全性。如果是这种情况,您需要在忽略的路径列表中添加另一条路径 / swagger-resources / configuration / security 。添加此路径后,当您调用任何被忽略的路径时,将不会调用 PreAuthTenantContextInitializerFilter
  • 此外,手动管理 PreAuthTenantContextInitializerFilter 的创建,而不是管理Spring。它将涉及从您的过滤器中删除@Component。您可以找到一个有效的示例here

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
       private TenantService service;
    
       @Autowired
       public SecurityConfiguration(TenantService service) {
           this.service = service;
       }
    
       @Override
       protected void configure(HttpSecurity http) throws Exception {
           http.addFilterBefore(
               new PreAuthTenantContextInitializerFilter(service),
               BasicAuthenticationFilter.class);
           ...
       }
    
       @Override
       public void configure(WebSecurity web) throws Exception {
           web.ignoring().antMatchers("/v2/api-docs", 
                "/configuration/ui",
                "/swagger-resources",
                "/configuration/security", "/swagger-ui.html",
                "/webjars/**", "/swagger-resources/configuration/ui",
                "/swagge‌r-ui.html", "/docs/**",
                "/swagger-resources/configuration/security");
       }
    }