【问题标题】:Spring webSecurity.ignoring() doesn't ignore custom filterSpring webSecurity.ignoring() 不会忽略自定义过滤器
【发布时间】:2017-01-02 07:55:03
【问题描述】:

我在我的 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);
    }

}

【问题讨论】:

    标签: java spring spring-mvc spring-security


    【解决方案1】:

    我认为您在 Filter 类中也需要它(extends RequestHeaderAuthenticationFilter),即

    public class EAccessAuthenticationFilter extends RequestHeaderAuthenticationFilter {
        public EAccessAuthenticationFilter() {
            super(new RequestMatcher() {
                            RequestMatcher matcher = new AntPathRequestMatcher("/v1/api1");
                return matcher.matches(request);    
    
            });
        }
    }
    

    【讨论】:

      【解决方案2】:

      我有正确的配置来忽略网络安全配置中的某些上下文路径,如下所示..

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

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

      【讨论】:

        【解决方案3】:

        我没有足够的声誉来添加评论,但是对于像我这样正在为kimhom's answer 寻找更多解释的人来说,WebSecurityConfigurerAdapter 会告诉 Spring Security 忽略通过它添加的任何过滤器。然后过滤器仍然被调用,因为@Component(或任何形式的@Bean)注释告诉Spring(再次)将过滤器添加到安全链之外。因此,当过滤器在安全链中被忽略时,它并没有被另一个(非安全?)链忽略。

        这解决了我两周的头痛问题。在我的情况下,我的自定义过滤器需要 SecurityContext 给出的 Authentication 对象,因为从未执行过安全链,所以它一直显示为 null。

        【讨论】:

          【解决方案4】:

          我总是发现最简单的方法是将此配置放入您的application.properties

          security.ignored=/api/**
          

          【讨论】:

          • 这是 security.ignored=/api/** (没有“spring”),这个解决方案也不起作用。但很高兴注意到!
          • 嗯,根据我的经验,您的原始代码和这都应该有效。你能发布你的相关过滤代码吗?
          • 也许您可以尝试将您的 http 安全配置更改为 http.authorizeRequests().antMatchers("/api/**").permitAll().anyRequest().authenticated()...,但我不知道您为什么需要在其他配置中使用它。
          • 我们是否有办法忽略使用属性文件,但仅适用于所有 GET 调用。还有其他的 HttpMethod 不应该被忽略吗?
          【解决方案5】:

          删除类 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

          【讨论】:

          • 我完全忘记了 spring 自动进行过滤器注册!谢谢
          • 同时检查你是否有一个 @Bean 注解的方法来创建你的 E...AuthenticationFilter 的一个实例。我有这样一个方法,我猜 Spring 会自动将我的过滤器添加到它的过滤器链中,而不是按照我想要的顺序。
          • 在我的情况下,我必须从我的自定义 AuthenticationFilter 中删除 @Bean 注释...这确保过滤器被绕过任何 web.ignoring() ant 匹配器,即使过滤器已在 httpsecurity 上注册跨度>
          【解决方案6】:

          经过几次测试,我意识到实际上我的配置没问题,只是理解问题。 spring.security.ignored=/api/** 不会绕过或关闭过滤器。实际上,每个请求仍然通过我的自定义过滤器,但不同之处在于 Spring Security 不介意身份验证状态或来自自定义过滤器的授予权限。

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

          【讨论】:

            猜你喜欢
            • 2016-10-26
            • 1970-01-01
            • 1970-01-01
            • 2021-11-04
            • 2020-05-01
            • 2011-08-23
            • 2014-07-28
            • 1970-01-01
            • 2018-12-06
            相关资源
            最近更新 更多