【发布时间】:2016-03-22 17:03:56
【问题描述】:
我正在寻找一种非侵入性的方式来为某些 api 调用添加验证码过滤器。
我的设置包含两个WebSecurityConfigurerAdapters,每个都有一个过滤器(不是验证码过滤器):
- 内部 api(“/iapi”在所有调用中使用过滤器 A,但也会忽略一些 public 请求,例如 /authenticate)
- 外部 api(“/eapi”在所有调用中使用过滤器 B)
如何在公共、内部 api 或外部 api 调用中添加过滤器之前 Spring Security 的东西?我不需要SecurityContext,只需要检查请求标头中的验证码,转发到filterChain(普通过滤器)或手动拒绝访问。我尝试在 web.xml 中声明一个过滤器,但这破坏了使用依赖注入的能力。
这是我的 Spring 安全配置:
@EnableWebSecurity
public class SpringSecurityConfig {
@Configuration
@Order(1)
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Filter filterA;
public InternalApiConfigurerAdapter() {
super(true);
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/public/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/iapi/**")
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(filterA, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return authenticationManager();
}
}
@Configuration
@Order(2)
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private FilterB filterB;
public ExternalApiConfigurerAdapter() {
super(true);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/external/**")
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(filterB, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return authenticationManager();
}
}
更新:目前我有一个在 web.xml 中声明的过滤器的工作配置。但是,它有与 Spring 上下文分离的缺点(例如,没有自动装配 bean),所以我正在寻找一个更好的利用 Spring 的解决方案。
总结:还有两个问题:
- 仅为特定的 url 添加过滤器 - 在任何配置中使用 beforeFilter(...) 会为该配置的所有 url 添加过滤器。 Antmatchers没有工作。我需要这样的东西:/iapi/captcha/、/external/captcha/、/public/captcha/*。
- 我有一个完全绕过 Spring Security 的公共 api:(web .ignoring() .antMatchers("/public/**");)。我需要绕过 Spring Security 但仍在那里声明一个过滤器,使用 Spring 自动装配但不一定是 Spring Security 功能,因为我的验证码过滤器仅以无状态方式拒绝或转发呼叫。
【问题讨论】:
-
您说的是
Filter A和Filter B。它们是您的验证码过滤器的占位符,还是您有真正的实现?如果是这样,您能否相应地更新您的问题? -
不确定它是否正是您要找的东西,但发现this answer 有一个类似的问题。不同之处在于它们在链的末尾添加了过滤器,并且配置是 XML 格式的,但是在 javaconfig 中,http.addFilterBefore() 也可以解决问题。
-
@ksokol 它们是当前系统的过滤器,我不想碰它们。
-
@SalvadorJuanMartinez 我认为它不会起作用。这是一个 xml 配置,我的主要问题是,我只想在不同配置中的特定路径之前添加一个过滤器 - 所以我不需要更改我的整个设置。
-
对不起,我想我没有解释清楚,我不是说要更改 XML 配置和/或在末尾添加过滤器,而是可以用作参考,因为它是如何向链中添加自定义过滤器的工作示例。它提供了有关如何正确实现过滤器的信息。在您的情况下,您可以坚持
.addFilterBefore()将过滤器插入您想要的位置。
标签: java spring spring-security captcha