1. 스프링 시큐리티 아키텍처
FilterChain
스프링 시큐리티는 서블릿 필터를 기반으로 동작합니다.
사용자가 애플리케이션에 요청을 보내면 서블릿 컨테이너는 요청 URI를 기반으로 HttpServletRequest
를 처리하는 FilterChain
을 생성합니다. 각 필터는 순차적으로 요청과 응답에 대한 여러 작업을 수행하게 됩니다.
스프링 웹 애플리케이션이라면 마지막에 오는 Servlet
은 DispatcherServlet
이 될겁니다.
DelegatingFilterProxy
스프링은 서블릿 컨테이너의 라이프사이클과 스프링의 ApplicationContext
사이를 연결할 수 있는 DelegatingFilterProxy
라는 필터 구현체를 제공합니다. 이 녀석이 모든 작업을 Filter
를 구현하는 스프링 bean 에 위임하게 됩니다.
FilterChainProxy
FilterChainProxy
는 스프링 시큐리티에서 제공하는 특별한 필터입니다. SecurityFilterChain
을 통해 많은 Filter
인스턴스에 작업을 위임할 수 있습니다. FilterChainProxy
는 bean 이기 때문에 DelegatingFilterProxy
로 래핑되어 있습니다.
SecurityFilterChain
SecurityFilterChain
은 현재 요청에 대해서 어떤 스프링 시큐리티 Filter
인스턴스를 호출할지 결정하기 위해 사용합니다.
SecurityFilterChain
의 Security Filter 는 일반적으로 bean 이며, FilterChainProxy
에 등록됩니다.
Security Filters
Security Filter 는 SecurityFilterChain
API를 사용하여 FilterChainProxy
에 삽입됩니다. 필터는 인증, 인가, 악의적인 공격으로부터의 보호 등 다양한 용도로 사용됩니다. 이러한 필터는 순차적으로 실행되어 적절한 순간에 호출되도록 보장합니다.
많은 필터들이 있지만 공식 문서에 따르면 필터의 순서를 알 필요까지는 없다고 합니다. 만일 순서를 알 필요가 있다면 FilterOrderRegistraion
코드를 확인하면 됩니다.
조금 더 이해하기 위해 제가 작성한 @Configuration
클래스를 가지고 왔습니다.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/hello").authenticated()
.anyRequest().permitAll()
)
.formLogin(formLogin -> formLogin
.defaultSuccessUrl("/")
.permitAll()
);
return http.build();
}
}
로그인 페이지(/login
)에 직접 접근해서 로그인이 성공하면 /
로 리다이렉트시키는 UsernamePasswordAuthenticationFilter
가 SecurityFilterChain
에 등록됩니다.
/hello
경로에 대해 인증된 요청만을 허가하고 다른 모든 경로에 대한 요청을 허용하는 AuthorizationFilter
가 SecurityFilterChain
에 등록됩니다.
이 외에도 스프링 부트는 기본적인 Security Filter 들을 등록합니다.
사용자의 요청은 이러한 모든 필터를 통과하게 되지만, 모든 필터가 동작하는 것은 아닙니다. 각 필터는 요청에 따라 동작 여부를 결정할 수 있고 동작할 필요가 없다면 다음 필터로 요청을 즉시 넘깁니다.
2. 시큐리티 필터
ExceptionTranslationFilter
ExceptionTranslationFilter
는 AccessDeniedException
과 AuthenticationException
에 대한 예외 처리를 담당합니다.
사용자가 인증되지 않았거나 AuthenticationException
이 발생한 경우 인증 프로세스를 시작합니다.
AccessDeniedException
이 발생한 경우 액세스가 거부됩니다. 이후 AccessDeniedHandler
가 접근 거부를 처리하기 위해 호출됩니다.
만약 해당하는 예외가 발생하지 않았으면 이 필터는 아무런 작업도 수행하지 않습니다.
참조
'공부방' 카테고리의 다른 글
CORS는 왜 필요할까? (0) | 2024.03.17 |
---|---|
[TIL] 스프링 시큐리티 인증 아키텍처와 프로세스 (0) | 2023.08.06 |
[TIL] 스프링 시큐리티 Quick Start (0) | 2023.08.05 |
[TIL 07/05] Spring MVC, REST API (0) | 2023.07.07 |
[TIL 07/04] 스프링 MVC (0) | 2023.07.06 |