有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在多个安全配置中使用Spring管理的独立自定义过滤器?

我已经尝试解决这个问题好几天了,考虑到我对Spring的有限经验,我已经没有什么想法了

我有一个简单的Hello World Spring启动应用程序,启用了安全性。我需要在不同版本(v1v2)上进行不同的安全配置。这意味着我需要两个不同的过滤器(扩展WebSecurityConfigurerAdapter)供每个配置使用。过滤器还必须由Spring管理,以便可以使用@Value注入环境变量

安全配置:

@EnableWebSecurity(debug = true)
public class WebSecurityConfig {

    @Order(1)
    @Configuration
    public static class Config1 extends WebSecurityConfigurerAdapter {

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            System.out.println("******** Config1:config");
            http.antMatcher("/api/v1/**")
                    .authorizeRequests()
                    .antMatchers("/api/v1/greet").permitAll()
                    .anyRequest().authenticated();
        }
    }

    @Order(2)
    @Configuration
    public static class Config2 extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            System.out.println("******** Config2:config");
            http.antMatcher("/api/v2/**")
                    .authorizeRequests()
                    .antMatchers("/api/v2/greet").permitAll()
                    .anyRequest().authenticated();
        }
    }
}

过滤器:

@Component
public class TestFilter1 extends BasicAuthenticationFilter {

    @Value("foo")
    private String foo;

    public TestFilter1(AuthenticationManager authManager) {
        super(authManager);
        System.out.println("************ TestFilter1:constructor");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("************ TestFilter1:doFilterInternal foo: " + this.foo);
        chain.doFilter(req, res);
    }
}

@Component
public class TestFilter2 extends BasicAuthenticationFilter {

    @Value("bar")
    private String bar;

    public TestFilter2(AuthenticationManager authManager) {
        super(authManager);
        System.out.println("************ TestFilter2:constructor");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("************ TestFilter2:doFilterInternal bar: " + this.bar);
        SecurityContextHolder.getContext().setAuthentication(null);
        chain.doFilter(req, res);
    }
}

控制器:

@RestController
public class GreetingController {

    @RequestMapping("/api/v1/greet")
    public String greet1() {
        System.out.println("************ GREETING V1");
        return "Hello Greeting 1";
    }

    @RequestMapping("/api/v2/greet")
    public String greet2() {
        System.out.println("************ GREETING V2");
        return "Hello Greeting 2";
    }
}

我的问题是,即使没有对过滤器进行任何显式分配(例如.addFilterBefore()),它们也会连接到两个配置

所以点击这里: http://localhost:8010/api/v2/greet 打印此文件:

************ TestFilter1:doFilterInternal foo: foo
************ TestFilter2:doFilterInternal bar: bar
************ GREETING V1

在点击其他版本时: http://localhost:8010/api/v2/greet 打印此文件:

************ TestFilter1:doFilterInternal foo: foo
************ TestFilter2:doFilterInternal bar: bar
************ GREETING V2

正如您所看到的,在这两种情况下,两个过滤器都被调用。在初始设置中,我将它们@Autowired作为Config1/2中的属性,并使用.addFilterBefore()附加,但注意到这两个过滤器都被调用。更神秘的是,它们仍然被称为addFilterBefore()

因此,问题可能是-如何使这些过滤器不会自动连接,同时仍将其作为弹簧组件

提前谢谢


共 (0) 个答案