이 글은 스프링 공식 문서를 보고 작성했습니다.
목차
1. 전체 구조
2. 필터와 필터체인
3. DelegatingFilterProxy
4. FilterChainProxy
5. SecurityFilterChain
6. 보안예외처리 과정
스프링 시큐리티는 클라이언트의 모든 http요청에 대한 필터링을 통해 보안기능을 제공한다.
이 글에서는 스프링 시큐리티의 필터링이 어떻게 구성되어있는지 알아보려한다.
위 그림의 한 부분씩 살펴보자.
서블릿 애플리케이션은 톰캣과 같은 서블릿 컨테이너 위에서 실행된다.
client의 요청이 발생했을때 컨테이너의 작동방식은 다음과 같다.
FilterChain
을 구성하여 ServletRequest
와 ServletResponse
를 전달한다. 이때 서블릿은 모든 필터를 통해 요청이 필터링 되고 나서 요청을 전달받는다.이때 필터의 특징은 다음과 같다.
request
와 response
, FilterChain
객체를 전달받는다. -> 요청에 관련된 작업후 FilterChain을 통해 다음 필터에 request
, response
넘겨줌.//필터의 의사코드
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
// 필터체인의 다음요소로 넘어가기전 작업들..
chain.doFilter(request, response); // 필터체인의 다음요소로 넘긴다.
// 필터체인의 마지막 요소들까지 요청이 전달된 후의 작업
}
스프링에서 제공하는 필터이다. api참고
이 필터는 프록시 역할을 하여 필터 체인에 속하지 않은 객체를 필터처럼 작동 시킬 수 있도록 해준다.
이를 통해서 필터의 로직을 필터체인 밖으로 꺼낼 수 있게된다.
스프링 시큐리티에서 사용하는 필터이다. DelegatingFilterProxy
와 같은 프록시 기능을 한다.
그렇다면 어떤 추가적인 기능이 필요하여 FilterChainProxy를 사용하는것일까?
이 필터의 기능 및 의미는 다음과 같다.
스프링 시큐리티의 필터()들이 묶여있는 필터체인이다.
애플리케이션에서 여러개의 SecurityFilterChain이 독립적으로 존재할 수 있으며 FilterChainProxy를 통해 요청에 매칭된다.
하나의 SecurityFilterChain으로 구성된 경우
두개 이상의 SecurityFilterChain으로 구성된 경우
SecurityFilterChain안의 SecurityFilter의 순서는 공식페이지에서 확인할 수 있다.
AccessDeniedException
과 AuthenticationExcetion
은 security filter중 하나인 ExceptionTranslationFilter
에서 처리한다.
이 필터는 자신의 다음순서의 필터중 예외가 발생한 경우를 캐치한다.
의사코드로 표현하면 다음과 같다.
try {
filterChain.doFilter(request, response);
} catch (AccessDeniedException | AuthenticationException ex) {
if (!authenticated || ex instanceof AuthenticationException) {
startAuthentication();
} else {
accessDenied();
}
}