我创建了一个自定义的Spring安全过滤器链,我希望排除以" / health"开头的所有URL。
这是我的过滤器配置:
@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();
}
当我开始申请时,我有这样的痕迹:
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/**']
当我调用我的服务时,我的这个网址:
https://localhost:9999/health
我有这个堆栈跟踪:
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
什么是平均健康状况有一个空的过滤列表?
答案 0 :(得分:3)
我遇到了同样的问题,我无法让“web.ignoring()。antMatchers(...)”工作。无论如何,我的自定义过滤器都会被调用。
有一种方法可以强制过滤器不影响给定的URL。我找到了这个答案: https://stackoverflow.com/a/19985323/7206367 这提供了一个可能的解决方案,旨在允许特定于筛选器的排除,但它也可用于强制URL排除覆盖。以下是我对这个问题的改编。
以下是支持方法的实现,但是您只需将其添加到HttpSecurity而不是自定义过滤器:
new DelegateRequestMatchingFilter(SECURITY_EXCLUSION_MATCHER, myCustomFilter);
支持代码:
@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();
}
}
}
或者
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);
}
}
}
然后,在你的过滤器构造函数中调用类似的东西:
public MyCustomFilter() {
super("/**");
}
相反,您可以接收一个RequestMatcher,匹配您想要忽略/排除的任何内容(例如:第一个示例中的SECURITY_EXCLUSION_MATCHER),并执行以下操作:
public MyCustomFilter(RequestMatcher excludeMatcher) {
super(new AExceptBRequestMatcher("/**", excludeMatcher));
}
答案 1 :(得分:1)
当你这样做时:
web.ignoring().antMatchers("/health");
与spring配置xml security="none"
相同。
这意味着此网址不会受到保护,并且返回一个空的过滤器列表意味着spring不会发送请求,因为没有过滤器,因此会抛出过滤器。意思是不安全的网址
编辑:我不确定什么是差异,但这肯定有用:
http.antMatchers("/health").permitAll();
这应该是.ignoring(),而应该放在HttpSecurity方法下,其余的都是