실제 서블릿에서 DelegataingFilterProxy를 통해 Filter를 호출하는데 이때 SecurityFilterChain에 등록된 내용들이 호출된다
즉 실제 Security Filter처리하는 부분을 담당한다
HttpSecurity.build()부분을 따라가다보면
return new DefaultSecurityFilterChain(this.requestMatcher, sortedFilters);
다음과같이 DefaultSecurityFilterChain을 반환해준다 즉 우리가 Bean으로 등록하는 SecurityFilterChain은 결국 DefaultSecrutiyFilterChain이었다
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
...
List<Filter> filters = getFilters(firewallRequest);
...
chain.doFilter(firewallRequest, firewallResponse);
...
}
private List<Filter> getFilters(HttpServletRequest request) {
for (SecurityFilterChain chain : this.filterChains) {
...
if (chain.matches(request)) {
return chain.getFilters();
}
}
return null;
}
DefaultSecurityFilterChain을 순회하면서 RequestMatcher내용이 일치하는지 판단하며 일치할경우 해당 FilterChain에 등록되어있는 Filter들을 반환하고 이를 doFilter를 통해 필터링을 진행한다
( DefaultSecurityFilterChain등록은 전 포스팅에서 설명한다 간략히 설명하면 WebSecurityConfiguration을 통해 FilterChainProxy가 등록되는데 이 과정에서 ignoring, requestMatch관련 Chain이 등록이 됨 )
if (chain.matches(request))
위 FilterChainProxy에서 matches를 통해 일치하는 Pattern에 대해서만 Filter를 등록시킨다
@Override
public boolean matches(HttpServletRequest request) {
return true;
}
어떠한 요청이든 true를 반환한다
@Override
public boolean matches(HttpServletRequest request) {
for (RequestMatcher matcher : this.requestMatchers) {
if (!matcher.matches(request)) {
return false;
}
}
return true;
}
And안에 있는 모든 RequestMatcher가 일치해야 한다
@Override
public boolean matches(HttpServletRequest request) {
for (RequestMatcher matcher : this.requestMatchers) {
if (matcher.matches(request)) {
return true;
}
}
return false;
}
한개만 일치해도 된다
해당 Matcher는 HandlerMappingIntrospector를 통해 Path를 지정하고 ServletPath에 상대적이라 '/'로 시작해야한다
해당 부분에서 찾아보니 /test로 등록해도 /test.html, /test.jsp 등과 같은 확장자들에 대해서도 match를 시켜 타입안전에 대해서는 Ant방식보다 조금더 떨어진다고 한다
@Override
public boolean matches(HttpServletRequest request) {
...
if (this.pattern.equals(MATCH_ALL)) {
return true;
}
...
}
AntPattenr에 일치하는경우 true를 반환한다
if (pattern.equals(MATCH_ALL) || pattern.equals("**")) {
pattern = MATCH_ALL;
...
}
패턴을 등록할때 /**(MATCH_ALL) or **를 사용할경우 MATCH_ALL로 자동으로 매핑된다
정상적으로 매핑되는걸 확인할 수 있다AntMatcher와 관련된부분은 AntPathMatcher.class를 확인해보자