java—如何使用spring管理的独立自定义过滤器和多个安全配置?

jhkqcmku  于 2021-07-13  发布在  Java
关注(0)|答案(0)|浏览(198)

我已经试着解决这个问题好几天了,考虑到我对spring的有限经验,我已经没有什么想法了。
我有一个简单的helloworld Spring 启动应用程序,启用了安全性。我需要不同版本的安全配置( v1 以及 v2 ). 这意味着我需要两个不同的过滤器(扩展 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() 他们仍然被称为。
因此,问题可能是-如何使这些过滤器不会自动连接,而仍然有他们作为Spring组件?
提前谢谢!

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题