Spring Security는 어떻게 인증을 처리할까? (1) Spring Security 아키텍쳐

Choizz·2023년 1월 20일
0

spring security

목록 보기
2/2
post-thumbnail

프로젝트에서 로그인을 구현할 때, 보통 Spring Security를 사용하게 된다.
그런데, 인증 처리 대부분이 자동화(?) 돼있어 인증 처리 흐름을 보기가 힘들다.
이번 포스팅은 Spring Security의 아키텍쳐에 대해 알아보자.

참고: https://docs.spring.io/spring-security/reference/servlet/architecture.html


Spring Security 아키텍쳐

  • 서블릿 필터는 자바에서 하는 API로 인터페이스 형태로 정의돼 있다. 서블릿 필터는 웹 요청이 들어오면 DispatcherServlet에 들어가기 전에 필터링을 가능하게 한다. 물론 클라이언트에게 응답이 들어가기 전에도 사용가능하다.

참고: Filter Chain이란??
하나 이상의 필터들이 연결돼있는 것을 말한다. 필터들은 doFilter() 메서드를 구현하여, 필터 체인을 형성한다.

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/filterchain.png

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/filterchain.png


스프링 시큐리티는 이러한 필터를 이용해 클라이언트 요청에 대한 인증을 처리한다.

아래 이미지에서 보이듯 DelegatingFilterProxy와 FilterChainProxy를 이용해서 스프링 시큐리티의 인증이 처리된다.

DelegatingFilterProxy와 FilterChainProxy는 클래스로서 Filter 인터페이스를 구현하고 있기 때문에 필터로서의 역할이 하다.

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/filterchainproxy.png

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/filterchainproxy.png

DelegatingFilterProxy

스프링은 Spring Security의 필터를 Bean으로 등록한 후 이 Bean들을 이용해서 보안과 관련된 작업을 처리하는데, DelegatingFilterProxy가 서블릿 컨테이너의 필터와 Spring Security 필터를 연결시켜 준다.
서블릿 컨테이너는 스프링에서 정의한 Bean들을 인식하지 못하지만 DelegatingFilterProxy가 Bean을 인식하게 해준다. 하지만, 명칭 그대로 DelegatingFilterProxy가 감싸고 있는 FilterChainProxy에게 등록한 필터들이 동작하도록 위임하는 역할만 한다.

FilterChainProxy

FilterChainProxy는 Spring Security에서 제공하는 Bean이다.

FilterChainProxy는 SecurityFilterChain으로 가는 진입점이라고 생각하면 된다. 그래서 디버깅을 할 때 FilterChainProxy에서 시작하는 것이 좋은 방법이 될 수 있다.

또한, RequestMatcher 인터페이스를 사용해서 요청으로 온 URL을 판단하여 어떤 필터를 동작시킬지를 결정한다. 아래 이미지에서 보면 각각 /api/**/** 에 맞춰 작동되는 SeurityFilterChain들이 있다.
만약 request의 URL이 /api/message라하면 FitlerChainProxy는 조금 더 구체적인 URL이 설정돼 있는 SecurityFilterChain(0)을 동작 시키고, 나머지 SecurityFilterChain들은 동작시키지 않는다.
그리고 /message라는 Url이 오게 되면 해당 URL에 맞는 SecurityFilterChain이 없으므로 제일 범용적인 URL이 설정돼 있는 SecurityFilterChain(n)을 작동시킨다.

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/multi-securityfilterchain.png

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/multi-securityfilterchain.png

SecurityFilterChain

SecurityFilterChain(0)을 보면 3개의 필터가 연결돼 있는 것을 볼 수 있고, SecurityFilterChain(n)을 보면 4개의 필터가 등록돼있는 것을 볼 수 있다. 이것은 각각의 SecurityFilterChain들이 서로 독립적으로 구성돼있다는 것을 알 수 있다. 그래서 특정 요청들을 무시하도록 설정하면 아무런 필터들도 작동시키지 않을 수 있다.

Security Filter

Spring Security에 등록된 많은 필터들은 SecurityFilterChain에 포함되어 있다. 이것들은 SecurityFilterChain API와 함께 FilterChainProxy에 등록돼있다. 아래 링크를 참고해 보자. 필터들의 순서를 알아두면 좋다.
참고: Security Filter

Handling Security Exceptions

ExceptionTranslationFilterAccessDeniedExceptionAuthenticationException을 Http Response로 넣는 것을 결정하는 필터이다. 즉, 예외를 발생시키는 것이다.

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/exceptiontranslationfilter.png

https://docs.spring.io/spring-security/reference/_images/servlet/architecture/exceptiontranslationfilter.png

  • 먼저 ExceptionTranslationFilter를 통과하면서 프로세스가 계속 진행된다.
  • 만약 인증되지 않은 유저이거나 AuthenticationException이 발생하면 바로 예외를 던지지 않고 인증 처리를 시작한다.
    • SecurityContextHolder(유저의 인증 정보를 가지고 있는 SecurityContext를 담은 바구니 느낌)를 비우고, HttpServletRequest를 다음 인증에 성공할 경우 재사용하기위해 RequestCache에 저장한다.
    • 그리고 AuthenticationEntryPoint에서 예외를 처리한다.
  • 만약 접근이 제한된 요청이라면, AccessDeniedHandler에서 AccessDeniedException을 처리한다.

만약 인증 관련한 예외를 던지지 않는다면 ExceptionTranslationFilter는 아무것도 하지 않는다.


정리

HttpServletRequest 
-> Servlet Filter 
-> DelegatingFilterProxy 
-> FilterChainProxy 
-> Url 매치 
-> SecurityFilterChain 선택 
-> Security Fitter 적용

지금까지 Spring Security가 어느 부분에서 작동하는 지, 어떻게 작동하는지에 대한 대략적인 아키텍쳐를 알아보았다. 다음 포스팅에는 Spring Security가 인증 처리를 어떻게 하는지를 알아보자.

profile
집중

0개의 댓글