BackEnd/Spring

[Spring] Spring Security (2) - Spring Security Filter Chain

JJangGu 2022. 2. 23. 21:18

스프링 시큐리티의 필터 체이닝에 대한 학습.

 

1. Spring Security Filter Chain

스프링 시큐리티는 서블릿 필터를 기반으로 동작합니다.

스프링 시큐리니는 내부적으로 각 필터가 책임을 갖게 하고, 서비스에 따라 추가/제거 되는 필터 체인을 가지고 있습니다.

네임스페이스 구성을 사용한다면, 내부적으로 FilterChainProxy 객체를 스프링 빈으로 등록하는데, FilterChainProxy는 접근제어, 로그인/로그아웃 등의 보안 관련 서블릿 필터들을 묶어서 실행해주는 기능을 제공합니다. 

 

2. DelegatingFilterProxy

스프링 책을 보다보면 '스프링 시큐리티를 위한 web.xml 설정'이라는 부분에서 DelegatingFilterProxy 라는 부분이 나오는데,

대부분이 넘어가지 않는 개념이지 않을까 생각이 듭니다.

서블릿 필터를 사용할때 이 DelegatingFilterProxy 를 web.xml 에서 선언해야 합니다. 그렇지 않으면 서블릿 컨테이너는 이를 무시할 것 입니다. 이유는 DelgatingFilterProxy 의 역할 때문인데, DelegatingFilterProxy는 Filter의 메소드를 Spring의 어플리케이션 컨텍스트에서 얻은 빈에게 위임하기 때문입니다. 

서블릿 컨테이너와 어플리케이션 컨텍스트 사이의 연결을 제공하는 것이 바로 DelegatingFilterProxy 입니다. 

 

DelegatingFilterProxy는 default 로 스프링 빈의 이름을 "springSecurityFilterChain" 으로 설정하는데, 실제 이 네임스페이스는 

spring-security.xml 설정의 스프링 시큐리티 네임스페이스를 처리하는 과정에서 등록됩니다.

이를 좀 더 자세히말해보면, 스프링 시큐리티 네임스페이스를 사용하면 내부적으로 FilterChainProxy 객체를 스프링 빈으로 등록하고, 

이 빈의 이름이 "springSecurityFilterChain" 입니다. 

 

  <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

위의 1번에서 잠깐 이야기했듯이, FilterChainProxy는 접근 제어, 로그인/로그아웃 등의 기능을 제공해주는 보안 관련 서블릿 필터들을 

묶어서 실행해주는 기능을 제공해줍니다. 

 

정리하자면,

web.xml 에서 설정한 DelegatingFilterProxy 는 스프링 시큐리티가 생성하는 FilterChainProxy에 필터처리를 위임하고,

이 FilterChainProxy 는 다시 여러필터를 체인 형식으로 갖고 있는 SecurityFilterChain 에 처리를 위임합니다.

 

위의 그림이 SecurityFilterChain 의 구조이고, 이 필터 체인을 이용해서 웹 요청에 대한 접근을 제어합니다. 

 

3. FilterChainProxy

위에서 계속하여 언급이 되었던 FilterChainProxy 입니다. 

 

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
  <sec:filter-chain-map path-type="ant">
     <sec:filter-chain pattern="/webServices/**" filters="
           securityContextPersistenceFilterWithASCFalse,
           basicAuthenticationFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />
     <sec:filter-chain pattern="/**" filters="
           securityContextPersistenceFilterWithASCTrue,
           formLoginFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />
  </sec:filter-chain-map>
</bean>

 

스프링 시큐리티의 서블릿 자원은 FilterChainProxy 에 포함되어 있고, FilterChainProxy는 스프링 시큐리티에서 제공하는 필터로

SecurityFilterChain 을 통해 많은 Filter 인스턴스에 위임할 수 있다고 정의되어있습니다.

FilterChainProxy 는 빈이므로, 앞서말한 내용과 같이 DelegatingFilterProxy 로 인해 매핑됩니다.

 

Spring 공식문서에서 그려지는 FilterChainProxy의 리퀘스트 매핑

SecurityFilterChain이 파란 점선안의 내용이라고 보시면 됩니다. FilterChainProxy도 웹에 대한 요청접근을 위임하기 위해

SecurityFilterChain을 가지고 있습니다. 다만 이것은 하나일 수도 있지만, 설정에 따라 여러개일 수 있습니다.

위의 그림을 보면 "/foo/**" 요청형식과 맞을때는 3개의 필터를 타도록 되어있고, "/bar/**" 요청에는 2개의 필터를 타게 만들어져 있습니다. 이 내용은 SecurityConfig 를 설정해보았거나 url pattern 을 설정해보았다면 이해할 것입니다.