스프링부트 해부학 : Security(2) - SecurityFilterChain

정윤성·2022년 6월 14일
0

스프링부트 해부학

목록 보기
15/20

역할

실제 서블릿에서 DelegataingFilterProxy를 통해 Filter를 호출하는데 이때 SecurityFilterChain에 등록된 내용들이 호출된다

즉 실제 Security Filter처리하는 부분을 담당한다

SecurityFilterChain

DefaultSecurityFilterChain

HttpSecurity

HttpSecurity.build()부분을 따라가다보면

return new DefaultSecurityFilterChain(this.requestMatcher, sortedFilters);

다음과같이 DefaultSecurityFilterChain을 반환해준다 즉 우리가 Bean으로 등록하는 SecurityFilterChain은 결국 DefaultSecrutiyFilterChain이었다

FilterChainProxy

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이 등록이 됨 )

RequestMatcher

if (chain.matches(request))

위 FilterChainProxy에서 matches를 통해 일치하는 Pattern에 대해서만 Filter를 등록시킨다

AnyRequestMatcher

@Override
public boolean matches(HttpServletRequest request) {
	return true;
}

어떠한 요청이든 true를 반환한다

AndRequestMatcher

@Override
public boolean matches(HttpServletRequest request) {
	for (RequestMatcher matcher : this.requestMatchers) {
		if (!matcher.matches(request)) {
			return false;
		}
	}
	return true;
}

And안에 있는 모든 RequestMatcher가 일치해야 한다

OrRequestMatcher

@Override
public boolean matches(HttpServletRequest request) {
	for (RequestMatcher matcher : this.requestMatchers) {
		if (matcher.matches(request)) {
			return true;
		}
	}
	return false;
}

한개만 일치해도 된다

MvcRequestMatcher

해당 Matcher는 HandlerMappingIntrospector를 통해 Path를 지정하고 ServletPath에 상대적이라 '/'로 시작해야한다

해당 부분에서 찾아보니 /test로 등록해도 /test.html, /test.jsp 등과 같은 확장자들에 대해서도 match를 시켜 타입안전에 대해서는 Ant방식보다 조금더 떨어진다고 한다

AntPathRequestMatcher

@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를 확인해보자

정리

  1. SecurityFilterChain는 내부적으로 Matcher를 통해 Match가되면 해당 FilterList를 반환해 처리를 위임시킨다
  2. RequestMatcher는 다양한 종류가 있다 ( AntPathRequestMatcher를 사용하는게 좋다 )
profile
게으른 개발자

0개의 댓글