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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39152803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:07:22  来源:igfitidea点击:

Spring webSecurity.ignoring() doesn't ignore custom filter

javaspringspring-mvcspring-security

提问by rattek

I have a set a custom authentication filter in my Spring 4 MVC + Security + Boot project. The filter does it's job well and now I want to disable the security for some URI (like /api/**). Here is my configuration

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

Unfortunately, when I call resource under /api/... the filter is still chained. I've added println in my filter and it's written to the console on every call. Do you know what's wrong with my configuration?

不幸的是,当我在 /api/... 下调用资源时,过滤器仍然是链接的。我在过滤器中添加了 println 并且每次调用时都会将它写入控制台。你知道我的配置有什么问题吗?

UPDATE

更新

Filter code:

过滤代码:

@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);
    }

}

回答by kimhom

remove @Component on class EAccessAuthenticationFilter,and like this:

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

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

回答by lancekf

I don't have enough reputation to add a comment, but for anyone like me who was looking for a little more of an explanation for kimhom's answer, WebSecurityConfigurerAdapterwill tell Spring Security to ignore any filters added through it. The filter was then still being invoked because the @Component(or any flavor of @Bean) annotation told Spring to add the filter (again) outside of the security chain. So while the filter was being ignored in the security chain, it was not being ignored by the other (non-security?) chain.

我没有足够的声誉来添加评论,但是对于像我这样正在为kimhom 的答案寻找更多解释的人WebSecurityConfigurerAdapter会告诉 Spring Security 忽略通过它添加的任何过滤器。然后仍然调用过滤器,因为@Component(或任何风格的@Bean)注释告诉 Spring 在安全链之外(再次)添加过滤器。因此,虽然过滤器在安全链中被忽略,但它并没有被其他(非安全?)链忽略。

This solved two weeks of headaches for me. In my case my custom filter needed the Authentication object given by the SecurityContextwhere it kept coming up as null because the security chain was never executed.

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

回答by Prashant Rajput

I had the correct configuration to ignore some context path in the web security configuration as below..

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

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

But I mistakenly had added @PreAuthorize(...) on my controller method and it seems like that method level security was overriding any security configuration set up at the start.

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

回答by Michael

I think you also need it in the Filterclass as well (extends RequestHeaderAuthenticationFilter) i.e.

我想你在Filter课堂上也需要它(extends RequestHeaderAuthenticationFilter)即

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

        });
    }
}

回答by Adam

I always found the easiest way to do this is to put this configuration in your application.properties:

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

security.ignored=/api/**

回答by rattek

After few tests I realized that in fact my configurations are ok and it's just a comprehension problem. The spring.security.ignored=/api/**doesn't bypass or turn off the filter. In reality every request still pass through my custom filter, but the difference is that Spring Security doesn't mind of the authentication status nor the granted authority coming from the custom filter.

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

I was wondering that the "ignored" property simply bypass the spring security filters. It sounds like I was totally wrong...

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