我已经试着解决这个问题好几天了,考虑到我对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组件?
提前谢谢!
暂无答案!
目前还没有任何答案,快来回答吧!