View
Spring Security - Architecture
rura6502 2021. 12. 21. 16:21 보안(Security)에는 크게 두가지 개념, 인증(authentication)
과 인가(authorization)
부분으로 나뉜다. 인증
은 이 사용자가 현재 사용자가 누구인지 확인하는 과정이며 인가
는 이 사용자가 특정 리소스를 사용할 자격이 있는지에 대한 부분이다. 예를들어 로그인
을 한다는 행위는 사용자가 누구인지 특정할 수 있는 인증
에 해당하고, 로그인 한 사용자가 일반 사용자인지, 관리자인지에 따라 관리자 페이지를 보여줄지 등을 결정하는 과정이 인가
과정이다. 스프링 시큐리티는 애플리케이션에 대한 인증, 인가를 지원하기 위해 여러개의 필터들로 구성된 필터 체인과 연관된 여러 모듈로 구성되어 있다. 이러한 필터들을 개발자가 직접 생성 또는 수정할 수 있도록 되어있다.
오염된 물을 정수하기 위해서 여러개의 필터를 장착하고 각 필터가 해당 필터의 단계, 기능에 맞는 오염 물질을 거르고 다음 필터로 넘겨주는, 정수기와 같은 구조로 이루어졌다고 생각해보면 이해하기 쉽다.
Servlet Filter to Spring Security Filter
잠깐 설명했던 스프링 시큐리이티의 필터는 서블렛의 Filter
구현체인데 스프링 시큐리티의 필터 중 하나인 LogoutFilter
를 보면 javax.servlet.Filter
를 구현했음을 볼 수 있다.
서블릿의 필터들은 아래 그림처럼 클라이언트의 요청이 들어오고 요청에 대한 응답을 했을 때, 일종의 단계로써 중간에 끼워넣을 수 있고 이러한 필터들을 FilterChain
이라는 이름으로 하나로 묶을 수 있다. 여기서 필터들이 하는 일은 서블릿 컨테이너가 서블릿에 전달할 HttpServletRequest
, HttpServletResponse
를 컨트롤(읽기, 쓰기)할 수 있다. 필터는 전달하는 방향에에 따라 정방향 호출 순서로만 호출되기 때문에 순서에 유의하여야 하는 특성이 있다.
스프링 시큐리티는 보안에 필요한 시큐리티용 필터들을 기존 애플리케이션에 동작중인 필터에 바로 끼워 넣는 것이 아니라 DelegatingFilterProxy
라는 필터를 하나 끼워넣고, 스프링의 라이프사이클과 빈 등록 메커니즘을 적용하기 위해 스프링의 ApplicationContext
와 연결할 수 있도록 연결하였다. DelegatingFilterProxy
의 역할은 스프링에서 빈으로 등록한 필터 정보들을 읽어서 서블릿 필터 체인 사이에서 동작할 수 있도록 세팅하는 역할을 한다.
이 DelegatingFilterProxy
는 FilterChainProxy
라는 빈래핑하고 있는데 FilterChainProxy
는 실제 스프링 시큐리티의 SecurityFilterChain
을 호출하는 호출자로써 동작한다. FilterChainProxy
의 역할은 빈으로 등록되어 있는 하나 이상의 SecurityFilterChain
을 HttpServletRequest
의 값에 따라 어떤 SecurityFilterChain
을 사용할 지 결정하는 역할을 할 수 있다.
정수기에서 사용자가 임의로 자유롭게 필터를 넣었다 뺄 수 있는 공간(DelegatingFilterProxy)이 있으며 그 공간은 실제로 여러개의 방(SecurityFilterChain)으로 나누어져있고 그 방에 사용자의 입맛에 따라 여러개의 필터(SecurityFilter)를 장착할 수 있다. 각 방은 서로에게 독립적이며 물은 하나의 방에서만 흐를 수 있으며 물이 공급되는 곳에선 물 색깔, 농도, 상태에 따라 어느 필터방으로 물을 보낼지 사용자가 설정할 수 있는 수도꼭지(FilterChainProxy)가 있다.
Security Exception, ExcetpionTranslationFilter
스프링 시큐리티 필터는 수많은 필터들이 기본적으로 제공되는데 그 중 익셉션 처리를 위한 특별한 필터인 ExceptionTranslationFilter
라는 필터는 스프링 시큐리티에서 발생하는 대표 익셉션인 AccessDeniedException
, AuthenticationException
을 처리하는 필터이다. 이 필터는 요청이 들어올 경우 설정에 따라 인증된 사용자일 경우 요청을 다음 필터로 진행시키고 인증이 안되었을 경우 AuthenticationEntryPoint
을 통해 클라이언트(사용자)에게 인증을 요청하는 행위를 수행한다. 스프링 시큐리티에서 시큐리티를 활성화시키고 별도의 설정을 하지 않았을 경우 모든 api의 요청이 login페이지로 리다이렉션되는 것을 볼 수 있는데 이 역할을 AuthenticationEntryPoint
가 하는 것이다. 접근이 완전 거부될 경우 발생하는 AccessDeniedException
의 경우 이 필터에서 AccessDeniedHandler
로 보내지게 된다.
즉 '인증되지 않은 사용자는 어떻게 처리할까?' 라는 행동을 정의하기 위해선AuthenticationEntryPoint
를 직접 구현해서 설정해야되고 접근 거부가 되었을 경우 행위에 대해선AccessDeniedHandler
를 구현해야 한다.
Reference
'Framework & Library & Tool > Spring&SpringBoot' 카테고리의 다른 글
Spring Security - Authentication Architecture: Example (0) | 2021.12.21 |
---|---|
Spring Security - Authentication Architecture (0) | 2021.12.21 |
Servlet, Servlet Container, Spring Container (0) | 2021.12.10 |
Spring Integration - 기본 개념 (0) | 2021.12.07 |
spring boot 코드 맛보기 (0) | 2017.01.24 |