Java Spring webSecurity.ignering()不';不要忽略自定义过滤器

Java Spring webSecurity.ignering()不';不要忽略自定义过滤器,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,在我的Spring4MVC+Security+Boot项目中,我设置了一个自定义身份验证过滤器。过滤器很好地完成了它的工作,现在我想禁用一些URI的安全性(如/api/**)。以下是我的配置: @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Override public void configure(WebSecurit

在我的Spring4MVC+Security+Boot项目中,我设置了一个自定义身份验证过滤器。过滤器很好地完成了它的工作,现在我想禁用一些URI的安全性(如
/api/**
)。以下是我的配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity.ignoring().antMatchers("/api/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
                 .anyRequest().authenticated()
              .and()
                 .addFilterBefore(filter, BasicAuthenticationFilter.class);
    }
}
不幸的是,当我调用
/api/…
下的资源时,过滤器仍然是链接的。我在过滤器中添加了
println
,每次调用时都会将其写入控制台。你知道我的配置有什么问题吗

更新

过滤代码:

@Component
public class EAccessAuthenticationFilter extends RequestHeaderAuthenticationFilter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("FILTER");
        if(SecurityContextHolder.getContext().getAuthentication() == null){
            //Do my authentication stuff
            PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(user, credential, authorities);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }  
        super.doFilter(request, response, chain);
     }

    @Override
    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

}

我总是发现最简单的方法是将此配置放在
应用程序中。属性

security.ignored=/api/**

经过几次测试后,我意识到实际上我的配置还可以,这只是一个理解问题。
spring.security.ignored=/api/**
不会绕过或关闭过滤器。实际上,每个请求仍然通过我的自定义过滤器,但区别在于Spring安全性不在乎身份验证状态,也不在乎来自自定义过滤器的授权


我想知道“忽略”属性是否只是绕过了spring安全过滤器。听起来我完全错了…

删除类EAccessAuthenticationFilter上的@Component,如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception {
   http.authorizeRequests()
             .anyRequest().authenticated()
          .and()
             .addFilterBefore(new EAccessAuthenticationFilter(), BasicAuthenticationFilter.class);
}

我没有足够的声誉来添加评论,但是对于像我这样想要更多解释的人,
websecurityConfigureAdapter
会告诉Spring Security忽略通过它添加的任何过滤器。由于
@Component
(或任何类型的
@Bean
)注释告诉Spring将过滤器(再次)添加到安全链之外,因此仍在调用过滤器。因此,当过滤器在安全链中被忽略时,另一个(非安全性?)链不会忽略它


这解决了我两周的头痛问题。在我的例子中,我的自定义筛选器需要由
SecurityContext
提供的身份验证对象,因为从未执行过安全链,所以它一直显示为null。

我有正确的配置,可以忽略web安全配置中的某些上下文路径,如下所示

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/v1/api1").antMatchers("/v1/api2");
}

但是我错误地在我的控制器方法上添加了@PreAuthorize(…),似乎该方法级别的安全性覆盖了一开始设置的任何安全配置。

我认为您在
过滤器
类中也需要它(
扩展RequestHeaderAuthenticationFilter


它是security.ignored=/api/**(不带“spring”),此解决方案也不起作用。但值得注意的是!嗯,根据我的经验,你的原始代码和这个都应该是有效的。您可以发布相关的筛选代码吗?也许您可以尝试将http安全配置更改为
http.authorizeRequests().antMatchers(“/api/**”).permitAll().anyRequest().authorized()…
,虽然我不知道你为什么需要在你的其他配置中使用这个。我们是否有办法忽略使用属性文件,但只用于所有GET调用。还有任何其他HttpMethod都不应该被忽略吗?我完全忘记了spring自动进行过滤器注册!谢谢。另外,请检查是否有@Bean注释的方法来创建E…AuthenticationFilter的实例。我有这样一个方法,我猜Spring会自动将我的过滤器添加到它的过滤器链中,而不是按照我想要的顺序。在我的情况下,我必须从我的自定义AuthenticationFilter中删除
@Bean
注释。。。这确保了对任何
web.ignering()
ant匹配器绕过筛选器,即使筛选器已在httpsecurity上注册
public class EAccessAuthenticationFilter extends RequestHeaderAuthenticationFilter {
    public EAccessAuthenticationFilter() {
        super(new RequestMatcher() {
                        RequestMatcher matcher = new AntPathRequestMatcher("/v1/api1");
            return matcher.matches(request);    

        });
    }
}