Spring webSecurity.ignoring()不会忽略自定义过滤器

时间:2016-08-25 18:55:00

标签: java spring spring-mvc spring-security

我在Spring 4 MVC + 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);
    }

}

6 个答案:

答案 0 :(得分:12)

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

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

https://github.com/spring-projects/spring-security/issues/3958

答案 1 :(得分:2)

我没有足够的声誉来添加评论,但是对于像我这样想要kimhom's answer的更多解释的人,WebSecurityConfigurerAdapter会告诉Spring Security忽略任何过滤器通过它添加。由于@Component(或@Bean的任何形式)注释告诉Spring在安全链之外再次添加过滤器,因此该过滤器仍被调用。因此,尽管在安全链中忽略了筛选器,但另一个(非安全性?)链也没有忽略筛选器。

这为我解决了两个星期的头痛。在我的情况下,我的自定义过滤器需要SecurityContext给定的Authentication对象,由于安全链从未执行过,因此它一直显示为null。

答案 2 :(得分:0)

我总是发现最简单的方法是将此配置放在application.properties中:

security.ignored=/api/**

答案 3 :(得分:0)

经过几次测试,我意识到实际上我的配置还可以,这只是一个理解问题。 inline std::string QByteArray::toStdString() const { return std::string(constData(), length()); } inline QByteArray QByteArray::fromStdString(const std::string &s) { return QByteArray(s.data(), int(s.size())); } 不绕过或关闭过滤器。实际上,每个请求仍然通过我的自定义过滤器,但区别在于Spring Security不介意身份验证状态,也不介意来自自定义过滤器的授权权限。

我想知道“被忽略”属性只是绕过弹簧安全过滤器。听起来我完全错了......

答案 4 :(得分:0)

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

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

但是我错误地在控制器方法上添加了@PreAuthorize(...),看来方法级别的安全性已覆盖了开始时设置的任何安全性配置。

答案 5 :(得分:0)

我认为您在 mongoDb.setPortBindings(List.of("27017:27017")); 类(Filter)中也需要它,即

extends RequestHeaderAuthenticationFilter