Spring/Spring Security

Spring Security (1) - FilterChainProxy

Spring Security 는 Servlet Filter 의 구현체들로 필터체인을 구성하여 인증 및 인가를 처리합니다.

 

Spring Security configuration

시큐리티 설정 구성은 WebSecurityConfigurerAdapter 를 상속받아 configure 메서드를 오버라이딩 하여 구성할 수 있습니다. 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .mvcMatchers("/").permitAll()  // 인증없이 접근 가능
        .mvcMatchers("/admin").hasRole("ADMIN")  // role 에 따라 구분
        .mvcMatchers("/user").hasRole("USER")  // role 에 따라 구분
        .anyRequest().authenticated();   // 기타 요청은 인증을 하기만 하면 됨
  }
}

@EnableWebSecurity 애노테이션은 스프링 시큐리티 설정임을 나타냄과 동시에 (부트의 경우) 기본 필터 설정을 하는 WebSecurityConfiguration 를 등록해줍니다.

 

 

FilterChainProxy 를 생성하는 일련의 과정을 간략화하였습니다. 템플릿 메소드 패턴등의 디자인 패턴 요소가 굉장히 많기 때문에 코드를 따라가면서 디자인 패턴 공부의 중요성을 느끼게 됩니다.

WebSecurityConfiguration 은 springSecurityFilterChain 이라는 이름의 bean 을 등록하는 데, 이 bean(springSecurityFilterChain) 은 FilterChainProxy 를 생성합니다. 이 FilterChainProxy 는 실질적으로 등록된 시큐리티 관련 필터들을 체이닝하는 프록시 클래스 입니다. 또한, 스프링은 DelegatingFilterProxy 를 서블릿 컨테이너의 필터체인으로 등록하여 DelegatingFilterProxy 가 doFilter 메서드에서 FilterChainProxy 를 사용하여 체이닝된 필터들을 사용하도록 합니다.

 

참고

더보기

서블릿 컨테이너는 요청을 받으면 등록된 필터의 doFilter 메소드를 실행합니다.

스프링에 구현된 필터들은 GenericFilterBean 이라는 스프링에서 제공하는 추상클래스를 상속받아 doFilter 메소드를 구현하면 된다. 위에서 설명한 DelegatingFilterProxy , FilterChainProxy 객체들도 GenericFilterBean을 상속받아 구현되었습니다.

외부에서 요청이 오면 서블릿 필터들을 거쳐 서블릿에게 도달하여 로직을 처리하는 데, 스프링 시큐리티는 이 과정중에 필터로직을 위임하는  DelegatingFilterProxy 를 두어 유연하게 원하는 필터 체인들을 넣을 수 있도록 디자인 되어 있습니다.

DelegatingFilterProxy

스프링 부트 사용시 SecurityFilterAutoConfiguration 에서 DelegatingFilterProxyRegistrationBean 을 생성하는데 (springSecurityFilterChain 빈 이름을 넘겨주며) 이 registration bean 이 상속하는  AbstractFilterRegistrationBean 에서 DelegatingFilterProxyRegistrationBean 의 getFilter 라는 메서드를 호출함으로써 DelegatingFilterProxy 클래스를 필터로 등록합니다.

위와 같이 Servlet Filter Chain 에는 필터를 위임할 DelegatingFilterProxy 를 등록하고 프록시로서의 역할을 합니다. 실제로 스프링 시큐리티의 필터 체인은 FilterChainProxy 가 수행합니다.

 

 

직접 소스코드를 보며 정리를 해보았습니다. 스프링 시큐리티의 구현을 보며 디자인 패턴에 대한 이해도가 부족한 것에 대한 반성과 스프링에 대해 얕게 알고 있었다는 생각이 들었습니다. 

혹시라도 제가 잘못 정리한 부분이나 추가하였으면 좋겠다는 부분이 있으시면 댓글 부탁드리겠습니다.

 

참고자료

https://www.inflearn.com/course/%EB%B0%B1%EA%B8%B0%EC%84%A0-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0