当前位置: 首页 > 知识库问答 >
问题:

如何根据@Profile向spring-security添加过滤器?

秦胡媚
2023-03-14

我试图定义两个不同的bean(都扩展了AbstractPreAuthenticatedProcessingFilter):一个用于在“开发”配置文件处于活动状态时从请求头(如USER_ID)中抓取一个头,另一个用于在“开发”配置文件不处于活动状态时从请求头中抓取一个JWT。(但从概念上讲,我实际上只是尝试基于bean本身的存在以编程方式注册过滤器)目前,我甚至没有尝试使用概要文件,因为我遇到了一个问题,无法将头自动注册到适当的过滤器链中。

该应用程序使用Spring-Boot 2.0.0.release,配置为使用嵌入式Tomcat,服务被注释为@RestController。下面是我的SecurityConfig类的简化版本:

@Configuration
@EnableWebSecurity(debug=true)
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {


@Bean
public UserIdAuthenticationFilter UserIdAuthenticationFilter() throws Exception {
    ...
}

@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
    ...
}


@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .cors().and()
        .csrf().disable()
        .headers().frameOptions().sameOrigin()
        .and()
        //.addFilter(jwtAuthenticationFilter())
        //.addFilter(UserIdAuthenticationFilter())
        .exceptionHandling()
        .and().authorizeRequests()
        .antMatchers("/", "/index.html", "/css/**", "/images/**", "/js/**").permitAll()
        .anyRequest()
        .authenticated()
        .antMatchers("/**").permitAll()
    ;


 }

}

运行应用程序的日志输出似乎表明筛选器正在找到...

 2018-04-04 09:43:02.907  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
 2018-04-04 09:43:02.907  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
 2018-04-04 09:43:02.907  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
 2018-04-04 09:43:02.908  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
 2018-04-04 09:43:02.908  INFO 7717 --- [ost-startStop-1] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
 2018-04-04 09:43:02.908  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpTraceFilter' to: [/*]
 2018-04-04 09:43:02.908  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webMvcMetricsFilter' to: [/*]
 2018-04-04 09:43:02.908  INFO 7717 --- [ LOOK HERE ] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'userIdAuthenticationFilter' to: [/*]
 2018-04-04 09:43:02.908  INFO 7717 --- [ LOOK HERE ] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'jwtAuthenticationFilter' to: [/*]
 2018-04-04 09:43:02.909  INFO 7717 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
 2018-04-04 09:43:02.922 DEBUG 7717 --- [ost-startStop-1] g.n.a.f.w.c.a.f.JwtAuthenticationFilter  : Initializing filter 'jwtAuthenticationFilter'
 2018-04-04 09:43:02.922 DEBUG 7717 --- [ost-startStop-1] g.n.a.f.w.c.a.f.JwtAuthenticationFilter  : Filter 'jwtAuthenticationFilter' configured successfully
 2018-04-04 09:43:02.922 DEBUG 7717 --- [ost-startStop-1] c.a.f.UserIdAuthenticationFilter : Initializing filter 'userIdAuthenticationFilter'
 2018-04-04 09:43:02.922 DEBUG 7717 --- [ost-startStop-1] c.a.f.UserIdAuthenticationFilter : Filter 'userIdAuthenticationFilter' configured successfully

现在应用程序正在运行,当我尝试访问该服务时,我看到spring转储了以下输出(带有debug):

 Security filter chain: [
   WebAsyncManagerIntegrationFilter
   SecurityContextPersistenceFilter
   HeaderWriterFilter
   CorsFilter
   LogoutFilter
   RequestCacheAwareFilter
   SecurityContextHolderAwareRequestFilter
   AnonymousAuthenticationFilter
   SessionManagementFilter
   ExceptionTranslationFilter
   FilterSecurityInterceptor
   ]

给定该输出,它向我表明安全筛选器链没有应用我的筛选器。

 Security filter chain: [
     WebAsyncManagerIntegrationFilter
     SecurityContextPersistenceFilter
     HeaderWriterFilter
     CorsFilter
     LogoutFilter
     JwtAuthenticationFilter <-----
     RequestCacheAwareFilter
     SecurityContextHolderAwareRequestFilter
     AnonymousAuthenticationFilter
     SessionManagementFilter
     ExceptionTranslationFilter
     FilterSecurityInterceptor
   ]

共有1个答案

廉博赡
2023-03-14

摘自关于Spring Security架构的文章:

Spring Security是作为链中的单个过滤器安装的,其关键类型是FilterChainProxy,原因很快就会变得显而易见。在Spring Boot应用程序中,安全过滤器是ApplicationContext中的@bean,默认情况下安装它,以便应用于每个请求。

可以有多个筛选器链,所有这些都由Spring Security在同一个顶级FilterChainProxy中管理,而所有这些都不为容器所知。Spring Security filter包含一个筛选器链的列表,并向与之匹配的第一个链发送一个请求。

另见:

  • 75.3向应用程序添加Servlet、筛选器或侦听器
  • 将@component添加到自定义Spring Security过滤器的含义是什么

至于配置文件,至少有两种方法可以满足您的需要:

@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class SecurityConfiguration {

    /**
     * Development security configuration.
     */
    @Profile("dev")
    @Configuration
    public static class DevSecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Bean
        public FilterRegistrationBean userIdAuthenticationFilter() {
            // ...
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.apply(commonSecurityConfiguration())
                    .and().addFilter(userIdAuthenticationFilter().getFilter());
        }
    }

    /**
     * Production security configuration.
     */
    @Profile("!dev")
    @Order(1)
    @Configuration
    public static class ProdSecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Bean
        public FilterRegistrationBean jwtAuthenticationFilter() {
            // ...
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.apply(commonSecurityConfiguration())
                    .and().addFilter(jwtAuthenticationFilter().getFilter());
        }
    }


    /**
     * Common security configuration reused by all profiles.
     */
    public static class CommonSecurityConfiguration
            extends AbstractHttpConfigurer<CommonSecurityConfiguration, HttpSecurity> {

        @Override
        public void init(HttpSecurity http) throws Exception {
            // Your basic configuration here:
            // http.cors().and()
            // ...
        }

        public static CommonSecurityConfiguration commonSecurityConfiguration() {
            return new CommonSecurityConfiguration();
        }
    }
}
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private final Environment environment;

    public SecurityConfiguration(Environment environment) {
        this.environment = environment;
    }

    @Profile("dev")
    @Bean
    public FilterRegistrationBean userIdAuthenticationFilter() {
        // ...
    }

    @Profile("!dev")
    @Bean
    public FilterRegistrationBean jwtAuthenticationFilter() {
        // ...
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Your basic configuration here:
        // http.cors().and()
        // ...

        if (environment.acceptsProfiles("dev")) {
            http.addFilter(userIdAuthenticationFilter().getFilter());
        } else {
            http.addFilter(jwtAuthenticationFilter().getFilter());
        }
    }
}

或者,您也可以使用application property而不是profile。

 类似资料:
  • 我有一个RESTful服务,它使用预先验证的令牌进行身份验证。我已经实现了我自己的preAuth过滤器,效果很好。我的问题是发送到我的服务的一些请求包含不适用于我的应用程序的BasicAuthoration。(我希望他们没有,他们也不应该,但他们有,我无法控制。) 现在,看起来Spring Security自动生成了一个BasicAuthorization过滤器,但是这个过滤器正在捕捉这些不相关的

  • 我想知道,在spring boot中是否有类(用于web应用程序)的注释?也许是? 我想在我的项目中添加一个自定义筛选器。 spring boot参考指南提到了关于,但我不确定如何使用它。

  • 问题内容: 我发现以下代码非常有效,可以让我在Python Shell中查看标准的1%的twitter firehose: 如何添加过滤器以仅分析来自特定位置的推文?我见过人们在其他与Twitter相关的Python代码中添加GPS,但我在Tweepy模块中找不到sapi的任何特定内容。 有任何想法吗? 谢谢 问题答案: 流API不允许同时按位置AND关键字进行过滤。 边界框不充当其他过滤器参数的

  • 问题内容: 我想知道,中的类(对于Web应用程序)是否有任何注释?也许@Filter吧? 我想在项目中添加自定义过滤器。 《 Spring Boot参考指南 》提到了关于 ,但是我不确定如何使用它。 问题答案: 如果您要设置第三方过滤器,则可以使用FilterRegistrationBean。例如相当于web.xml 这些将是@Configuration文件中的两个bean 上面已经用spring

  • 通过,我可以轻松地在方法中向添加一个筛选器。 如何使用添加筛选器?我必须使用XML吗? 为了帮助其他人更容易地理解Spring Web配置,我绘制了下面的插图。 比起记住那么多东西,查它还不那么痛苦。 和一篇关于Spring Web初始化的好文章: http://www.kubrynski.com/2014/01/commanding-spring-web-initialization.html

  • 我想在我的项目中添加一个自定义筛选器。 Spring Boot参考指南提到了关于,但我不确定如何使用它。