회사 업무/기술 연구편

[Security] Spring Security Framework 개념편

코드몬스터 2025. 3. 4. 09:40
728x90

 

 

 

 

 

관련 블로그 글

[Security] 접근 제어 정책(Access Control) - https://jm-baek.tistory.com/370

[Security] Spring Security Framework 개념편 - https://jm-baek.tistory.com/386

[Security] 인증(Authentication) with Spring Security - https://jm-baek.tistory.com/385

[Security] 인가(Authorization) with Spring Security - https://jm-baek.tistory.com/389

[Security] Spring Security Framework 도입편 - https://jm-baek.tistory.com/388

 

목차

  1. 들어가기에 앞서
  2. Spring Security
    • Spring Security Architecture
      1) FilterChain
      2) DelegatingFilterProxy
      3) FilterChainProxy
      4) SecurityFilterChain
  3. 참고 사이트

 

들어가기에 앞서

접근 제어 정책 및 기타 보안 기능을 도입하기 위해서 

스프링 애플리케이션의 보안 기능을 담당하는 Spring Security 프레임워크를 공부해보자.


Spring Security

Spring Security는 인증(Authentication), 인가(Authorization), 그리고 일반적인 공격으로부터의 보호(Security Protection)를 제공하는 프레임워크입니다.
명령형(Imperative) 및 리액티브(Reactive) 애플리케이션을 모두 안전하게 보호할 수 있도록 강력한 지원을 제공하며,
Spring 기반 애플리케이션 보안의 사실상 표준(de-facto standard) 으로 자리 잡고 있습니다.

 

Spring Security Architecture

1️⃣ FilterChain

클라이언트가 애플리케이션에 요청을 보내면 컨테이너는 요청 URI 경로를 기반으로 해당 요청을 처리할 Filter 인스턴스와 Servlet을 포함하는 FilterChain을 생성합니다.

 

Spring MVC 애플리케이션에서는 이 Servlet이 DispatcherServlet의 인스턴스입니다.
단일 HttpServletRequest 및 HttpServletResponse를 처리할 수 있는 Servlet은 최대 한 개지만, 여러 개의 Filter를 사용할 수 있습니다.

 

Filter는 다음과 같은 역할을 수행할 수 있습니다.

  • 하위 Filter 인스턴스나 Servlet이 호출되지 않도록 방지
    → 이 경우, Filter는 보통 HttpServletResponse를 직접 작성하여 응답을 반환합니다.
  • 하위 Filter 인스턴스 및 Servlet이 사용할 HttpServletRequest 또는 HttpServletResponse를 수정

Filter의 강력한 기능은 FilterChain을 통해 제공됩니다.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
	// do something before the rest of the application
    chain.doFilter(request, response); // invoke the rest of the application
    // do something after the rest of the application
}

 

 

2️⃣ DelegatingFilterProxy

Spring은 DelegatingFilterProxy라는 Filter 구현체를 제공하며, 이를 통해 서블릿 컨테이너의 라이프사이클과 Spring의 ApplicationContext를 연결할 수 있습니다. 서블릿 컨테이너는 자체 표준을 사용하여 Filter 인스턴스를 등록할 수 있지만, Spring에서 정의한 Bean을 인식하지는 않습니다.


DelegatingFilterProxy를 사용하면 서블릿 컨테이너의 표준 방식으로 Filter를 등록하면서도, 실제 작업을 수행하는 Spring의 Filter Bean에 요청을 위임할 수 있습니다.

 

이제, DelegatingFilterProxy가 Filter 인스턴스 및 FilterChain에서 어떻게 동작하는지 그림으로 이해할 수 있습니다.

 

Servlet의 기본 Filter 동작 방식

일반적으로 서블릿 컨테이너(예: Tomcat, Jetty)에서 Filter는 다음과 같이 동작합니다.

  1. 클라이언트 요청이 들어오면, 서블릿 컨테이너가 등록된 Filter들을 확인합니다.
  2. FilterChain에 등록된 Filter들을 순차적으로 실행합니다.
  3. 모든 Filter가 실행된 후, 최종적으로 요청을 실제 서블릿(DispatcherServlet)으로 전달합니다.
  4. 서블릿의 응답이 다시 FilterChain을 거쳐 클라이언트로 반환됩니다

하지만, ⭐서블릿 컨테이너는 Spring의 ApplicationContext를 직접 알지 못하기 때문에, Spring에서 관리하는 Bean을 Filter로 직접 등록할 수 없습니다.
이 문제를 해결하기 위해 Spring이 제공하는 DelegatingFilterProxy를 사용합니다.

 

DelegatingFilterProxy의 동작 원리

  1. 서블릿 컨테이너에 DelegatingFilterProxy 등록
    • web.xml이나 Spring Boot의 FilterRegistrationBean을 사용하여 등록 가능
    • 이때 DelegatingFilterProxy는 단순한 프록시 역할만 수행
  2. DelegatingFilterProxy가 Spring ApplicationContext에서 지정한 Filter Bean을 찾음
    • DelegatingFilterProxy의 filter-name과 같은 이름의 Spring Bean을 찾아서 실제 동작을 위임
  3. 실제 Filter 로직은 Spring이 관리하는 Bean에서 실행됨

 

3️⃣FilterChainProxy

Spring Security의 서블릿 지원 기능은 FilterChainProxy 내부에 포함되어 있습니다.

 

FilterChainProxy는 Spring Security에서 제공하는 특수한 Filter로,

여러 개의 Filter 인스턴스를 SecurityFilterChain을 통해 관리하고 실행하는 역할을 합니다.

 

또한, FilterChainProxy는 Spring의 Bean으로 관리되기 때문에, 서블릿 컨테이너에 등록하려면 일반적으로 DelegatingFilterProxy를 사용하여 감싸야 합니다.

 

아래 이미지는 FilterChainProxy의 역할과 동작 방식을 보여줍니다.

 

 

4️⃣ SecurityFilterChain

SecurityFilterChain은 FilterChainProxy 가 현재 요청에 대해 ⭐어떤 Spring Security 필터들을 실행할지 결정하는 역할을 합니다.

아래 이미지는 SecurityFilterChain의 역할을 보여줍니다.

 

  1. Spring Security의 서블릿 지원을 위한 시작점 제공
    • Spring Security의 서블릿 기반 보안 기능이 실행되는 핵심 지점이므로,
      디버깅할 때 FilterChainProxy에 중단점(Breakpoint)을 설정하면 유용합니다.
  2. Spring Security의 필수 작업 수행
    • SecurityContext를 자동으로 정리하여 메모리 누수를 방지합니다.
    • HttpFirewall을 적용하여 특정 웹 공격을 방어합니다. (예: CRLF 인젝션 방지)
  3. 더 유연한 보안 필터 체인 적용
    • 일반적인 서블릿 필터(Filter)는 URL 패턴 기반으로만 실행됩니다.
    • 그러나 FilterChainProxy는 RequestMatcher 인터페이스를 활용하여 요청의 다양한 요소를 기준으로 필터 실행을 결정할 수 있습니다.

아래 이미지는 여러 개의 SecurityFilterChain 인스턴스가 존재하는 구조를 보여줍니다.

 

 


참고 사이트

  1. 스프링 시큐리티 구조(https://docs.spring.io/spring-security/reference/servlet/architecture.html)