绕过Spring安全过滤器链

[英]Bypassing the Spring security filter chain


I created a custom Spring security filter chain and I want to exclude all url beginning with "/health".

我创建了一个自定义的Spring安全过滤器链,我想要排除所有以“/ health”开头的url。

here is my filter configuration:

这是我的过滤器配置:

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

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .exceptionHandling()
            .authenticationEntryPoint(ssoEntryPoint());
    http
            .authorizeRequests()

            .antMatchers("/images/**").permitAll()
            .antMatchers("/scripts/**").permitAll()
            .antMatchers("/styles/**").permitAll()
            .antMatchers("/vendor/**").permitAll()
            .antMatchers("/views/**").permitAll()
            .antMatchers("/index.html").permitAll()
            .antMatchers("/api/**").authenticated();

    http    // login configuration
            .addFilterAfter(ssoSpringSecurityFilter(), BasicAuthenticationFilter.class);

    http    //logout configuration
            .logout()
            .logoutSuccessHandler(logoutHandler());

    http.csrf().disable();

}

when I start my application i have this trace:

当我启动我的应用程序时,我有这样的痕迹:

  2016-01-29 12:59:23.729  INFO 10572 --- [ost-startStop-1] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: Ant [pattern='/health'], []
  2016-01-29 12:59:23.814 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/images/**']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/modules/**']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/scripts/**']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/styles/**']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/vendor/**']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/views/**']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/index.html']
  2016-01-29 12:59:23.816 DEBUG 10572 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'authenticated', for Ant [pattern='/api/**']

When I invoque my service my this url:

当我调用我的服务时,我的这个网址:

  https://localhost:9999/health

I have this stack trace:

我有这个堆栈跟踪:

  2016-01-29 13:05:34.076  INFO 10572 --- [nio-9999-exec-4] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
  2016-01-29 13:05:34.076  INFO 10572 --- [nio-9999-exec-4] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
  2016-01-29 13:05:34.121  INFO 10572 --- [nio-9999-exec-4] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 45 ms
  2016-01-29 13:05:34.136 DEBUG 10572 --- [nio-9999-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/health'; against '/css/**'
  2016-01-29 13:05:34.136 DEBUG 10572 --- [nio-9999-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/health'; against '/js/**'
  2016-01-29 13:05:34.136 DEBUG 10572 --- [nio-9999-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/health'; against '/images/**'
  2016-01-29 13:05:34.137 DEBUG 10572 --- [nio-9999-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/health'; against '/**/favicon.ico'
  2016-01-29 13:05:34.137 DEBUG 10572 --- [nio-9999-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/health'; against '/error'
  2016-01-29 13:05:34.137 DEBUG 10572 --- [nio-9999-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/health'; against '/health'
  2016-01-29 13:05:34.137 DEBUG 10572 --- [nio-9999-exec-4] o.s.security.web.FilterChainProxy        : /health has an empty filter list

What is mean health has an empty filter list?

什么是平均健康有一个空的过滤列表?

2 个解决方案

#1


2  

I had the same problem, and I could never get the "web.ignoring().antMatchers(...)" to work. My custom filter kept getting called regardless.

我有同样的问题,我永远无法让“web.ignoring()。antMatchers(...)”工作。我的自定义过滤器不断被调用。

There is a way you can force the filter to not affect given URLs. I found this Answer: https://stackoverflow.com/a/19985323/7206367 which gave a possible solution intended to allow filter-specific exclusions, but it can also be used to force the URL exclusion override. Below is my adaptation for this problem.

有一种方法可以强制过滤器不影响给定的URL。我找到了这个答案:https://stackoverflow.com/a/19985323/7206367,它提供了一个可能的解决方案,旨在允许特定于筛选器的排除,但它也可用于强制URL排除覆盖。以下是我对这个问题的改编。

Below are the implementations of the support methods, but then all you have to do is just add this to HttpSecurity instead of your custom filter:

下面是支持方法的实现,但是您只需将其添加到HttpSecurity而不是自定义过滤器:

new DelegateRequestMatchingFilter(SECURITY_EXCLUSION_MATCHER, myCustomFilter);

The support code:

支持代码:

@Configuration
@EnableWebSecurity
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    ...

    private static final RequestMatcher SECURITY_EXCLUSION_MATCHER;
    static {
        String[] urls = new String[] {
                "/login",
                "/refreshToken",
                "/health",
                "/ping"
        };

        //Build Matcher List
        LinkedList<RequestMatcher> matcherList = new LinkedList<>();
        for (String url : urls) {
            matcherList.add(new AntPathRequestMatcher(url));
        }

        //Link Matchers in "OR" config.
        SECURITY_EXCLUSION_MATCHER = new OrRequestMatcher(matcherList);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().requestMatchers(SECURITY_EXCLUSION_MATCHER);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                .requestMatchers(SECURITY_EXCLUSION_MATCHER).permitAll()

    }

    ...

    /**
     * Since the "web.ignoring()..." is not stopping the Custom Filter from acting on the ignored urls,
     * this delegation class will force a check on the Security Exclusion list before allowing the
     * Custom Filter to process anything. 
     */
    public static class DelegateRequestMatchingFilter implements Filter {
        private Filter delegate;
        private RequestMatcher ignoredRequests;

        public DelegateRequestMatchingFilter(RequestMatcher matcher, Filter delegate) {
            this.ignoredRequests = matcher;
            this.delegate = delegate;
        }

        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            if(ignoredRequests.matches(request)) {
                chain.doFilter(req,resp);
            } else {
                delegate.doFilter(req,resp,chain);
            }
        }

        public void init(FilterConfig filterConfig) throws ServletException {
            delegate.init(filterConfig);
        }

        public void destroy() {
            delegate.destroy();
        }
    }
}

Or

要么

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

/**
 * <p>
 * This matcher will return all matches which match <cdoe>baselineMatches</code>, if
 * and only if, those matches are not matched by <code>ignoreMatches</code>.
 * </p>
 * 
 * <p>
 * This matcher first checks <code>ignoreMatches</code>. If a given request is found
 * as a match to <code>ignoreMatches</code>, this matcher will return false (not a match).
 * If a given request does not match <code>ignoreMatches</code>, then this matcher returns
 * whether or not that request matches <code>baselineMatches</code>.
 * </p>
 * 
 * Effectively:<br>
 * <code>
 * if (ignoreMatches.matches(request)) {
 *      return false;
 * } else {
 *      return baselineMatches.matches(request);
 * }
 * </code>
 * @param baselineMatches Matcher used to determine a request match.
 * @param ignoreMatches Matcher used to exclude matches from the baselineMatcher.
 */
public class AExceptBRequestMatcher implements RequestMatcher {
    private RequestMatcher baselineMatches;
    private RequestMatcher ignoreMatches;

    public AExceptBRequestMatcher(String baselineMatches, RequestMatcher ignoreMatches) {
        this(new AntPathRequestMatcher(baselineMatches), ignoreMatches);
    }

    public AExceptBRequestMatcher(RequestMatcher baselineMatches, RequestMatcher ignoreMatches) {
        this.baselineMatches = baselineMatches;
        this.ignoreMatches = ignoreMatches;
    }

    @Override
    public boolean matches(HttpServletRequest request) {
        if (ignoreMatches.matches(request)) {
            return false;
        } else {
            return baselineMatches.matches(request);
        }
    }
}

And then, in your filter constructor where you call something like:

然后,在您的过滤器构造函数中,您调用类似于:

public MyCustomFilter() {
    super("/**");
}

Instead you can take in a RequestMatcher matching whatever you want to ignore/exclude (ex: the SECURITY_EXCLUSION_MATCHER from the first example), and do this:

相反,您可以使用RequestMatcher来匹配您想要忽略/排除的任何内容(例如:第一个示例中的SECURITY_EXCLUSION_MATCHER),并执行以下操作:

public MyCustomFilter(RequestMatcher excludeMatcher) {
    super(new AExceptBRequestMatcher("/**", excludeMatcher));
}

#2


1  

When you are doing this:

当你这样做:

web.ignoring().antMatchers("/health");

Is the same as spring configuration xml security="none".

与spring配置相同xml security =“none”。

It means that this url will not be secured and returning a empty filter list means that spring won't send the request throw his filter because there is not filters.. Meaning unsecured url

这意味着这个url不会被保护并返回一个空的过滤器列表意味着spring不会发送请求抛出他的过滤器,因为没有过滤器..意思是不安全的url

EDIT: I am not sure what are the diffrences but this works for sure:

编辑:我不确定什么是差异,但这肯定有效:

http.antMatchers("/health").permitAll();

This should be instead of .ignoring() and should be put under the HttpSecurity method with all the rest

这应该是.ignoring(),而不应该放在HttpSecurity方法下


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2016/01/29/1feeaacce17fae9da673250028edf1d8.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号