java如何在多个安全配置中使用Spring管理的独立自定义过滤器?
我已经尝试解决这个问题好几天了,考虑到我对Spring的有限经验,我已经没有什么想法了
我有一个简单的Hello World 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()
因此,问题可能是-如何使这些过滤器不会自动连接,同时仍将其作为弹簧组件
提前谢谢
共 (0) 个答案