Spring Security 개요

Lee Seung Jae·2022년 2월 21일
0

Spring Security

목록 보기
2/4

📌 Spring Security

Spring SecurityServlet Filters를 기반으로 동작한다.

Spring Security는 인증, 권한 부여 및 보호를 제공하는 프레임워크이다.

전체적인 구조는 위와 같다.

Gradle 설정

plugins {
	  id 'io.spring.dependency-management' version "1.0.10.RELEASE"
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
}

📌 Filter

그래서 필터의 역할을 먼저 아는것이 중요한데,

Filter 영어 단어만 봐도 뭔가를 필터로 걸러주는 느낌이 난다.

업무중에 통신 하나하나의 로그를 다 찍는 과정을 Filter를 통해서 구현했던 경험이 있다.

이 필터를 줄줄이 연결하면 FilterChain이 되는 것이다.

다음은 스프링 공식문서에서 FilterChain의 구조를 가져왔다.

구조


클라이언트는 서버에 요청을 보내고 컨테이너는 요청 URI를 기반으로 HttpServletRequest를 처리하는 필터와

필터체인을 생성한다. Spring MVC에서의 ServletDispatcherServlet이 된다.

Filter 인터페이스를 구현하면 doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

메소드를 구현해주어야 한다.

chain.doFilter()를 호출하면 다음 필터를 차례대로 수행하는 것이다.

이렇게 필터들이 쭉 연결되어 기능을 수행한다고 생각하면 된다.

📌 DelegatingFilterProxy

구조


설명

SpringServlet 컨테이너의 라이프사이클과

SpringApplicationContext 사이의 연결을 허용하는

DelegatingFilterProxy라는 필터를 제공한다.

이 필터는 Servlet Filter로 애플리케이션 컨텍스트에서 요청한 것을 스프링 컨테이너에 생성된

Bean Filter를 찾고 그 필터를 호출한다.

DelegatingFilterProxy는 컨테이너가 시작되기 전에 필터를 등록해야 하기 때문에 중요하다.

📌 FilterChainProxy

Spring Security의 서블릿 지원은 FilterChainProxy에 포함되어 있다.

FilterChainProxySecurityFilterChain을 통해 여러 필터 인스턴스에 위임할 수 있도록

시큐리티에서 제공하는 특수 필터이다.

FilterChainProxyBean이라서 DelegatingFilterProxy안에 포함된다.

구조

이제보니 구조가 좀 잡혀가는것 같다.

클린코드와 자바의 정석을 읽었더니 시큐리티 아키텍처가 이해되는건 무엇일까.... 🤔🤔🤔

📌 SecurityFilterChain

SecurityFilterChain은 클라이언트에서 필터를 돌다가 DelegatingFilterProxy에 들어온 요청을

받아서 이 요청에 대해 처리해야 하는 Security Filter를 찾아 수행한다.

구조

📌 Security Filter

핵심인 시큐리티 필터이다. 이 필터는 SecurityFilterChain API를 사용해

FilterChainProxy에 삽입된다. 이 필터들은 순서가 중요하다.

필터의 순서를 알 필요는 없다.

근데 알아두면 유용하게 사용할 수는 있다.

필터에는 다음과 같은 필터들이 존재하고 위에서 아래로 순서가 매겨져 있다.

  • ChannelProcessingFilter
  • WebAsyncManagerIntegrationFilter
  • SecurityContextPersistenceFilter
  • HeaderWriterFilter
  • CorsFilter
  • CsrfFilter
  • LogoutFilter
  • OAuth2AuthorizationRequestRedirectFilter
  • Saml2WebSsoAuthenticationRequestFilter
  • X509AuthenticationFilter
  • AbstractPreAuthenticatedProcessingFilter
  • CasAuthenticationFilter
  • OAuth2LoginAuthenticationFilter
  • Saml2WebSsoAuthenticationFilter
  • UsernamePasswordAuthenticationFilter
  • OpenIDAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter
  • ConcurrentSessionFilter
  • DigestAuthenticationFilter
  • BearerTokenAuthenticationFilter
  • BasicAuthenticationFilter
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • JaasApiIntegrationFilter
  • RememberMeAuthenticationFilter
  • AnonymousAuthenticationFilter
  • OAuth2AuthorizationCodeGrantFilter
  • SessionManagementFilter
  • ExceptionTranslationFilter
  • FilterSecurityInterceptor
  • SwitchUserFilter

블럭이 쳐져있는 필터들을 유의해서 더욱 살펴봐야 하겠다.

📌 Handling Security Exceptions

위에서 ExceptionTranslationFilter를 사용하면 AccessDeniedException이나,

AuthenticationException을 HTTP Response로 변환할 수 있다.

  1. 일단 들어온 요청에서 FilterChain.doFilter()로 나머지 애플리케이션을 호출한다.
  2. 사용자가 인증이 되지 않았거나, AuthenticationException이 발생한 경우에 인증을 진행한다.

    이 경우 사용자가 성공적으로 인증되면 RequestCache에 사용자를 저장하고 이 캐시를 사용하여 원래 요청을 쭉 진행한다.
  3. 여기서 AccessDeniedException이 발생하게 되면 액세스는 거부되고, AccessDeniedHandler는 이 예외를 처리하기 위해 호출된다.

이 설정이 AccessDeniedExceptionAuthenticationException에 대한 예외처리가 없다면

ExceptionTranslationFilter는 아무것도 수행하지 않는다.

정리

여기까지가 일단 스프링 시큐리티의 기본적인 흐름이다.

다음 포스팅에서는 인증(Authentication) 에 대해서만 쭉 다뤄보는것으로 하겠다.

어렴풋이 알고 있는 기본값들에 대해서만 사용할게 아니라 입맛에 따라 커스텀하며 필터를 작업해주는 것이

개발자의 역량이라고 생각한다. 이게 뒷받침되려면 당연히 이런 공식문서를 읽어보는게 답이다.

전체적인 아키텍처의 흐름을 알아야 잘 설계할 수 있다.

아무튼 이 아키텍처를 공부함으로써 어제의 나보다는 오늘이 더 성장했다.

업무나 프로젝트에 들어간 시큐리티에 대한 코드를 보면 지금보다 더 이해할거라고 자신한다 🔥🔥🔥🔥

profile
💻 많이 짜보고 많이 경험해보자 https://lsj8367.tistory.com/ 블로그 주소 옮김

0개의 댓글