본문 바로가기
카테고리 없음

스프링 시큐리티 & 필터

코동이 2021. 10. 7.

 

 

 톰캣을 서블릿 컨테이너라고도 불리는데 다수의 서블릿으로 톰캣이 구성되어 있기 때문이다. spring에서 모든 요청은 dispatcherServlet에서 처음 처리를 시작하는데, 그 이전에 filter를 거쳐야 한다.

 

 이 filter들은 chain으로 연결되어 있고, 반드시 모든 요청들은 이 filter를 하나하나씩 다 거쳐야 한다. 이 때 스프링 시큐리티 필터가 작동한다.

 

 경우에 따라서 다양한 필터 정책을 적용할 수 있으며 역할은 시큐리티에서 DelegatingFilterProxy가 한다. 이 필터를 메인 필터에 끼우고, 그 아래에 여러개의 SeurityFilterChain을 등록한다. 각 필터 체인의 적용 경로는 /api/**, /admin/** 등 다양한 정책의 경우를 적용할 수 있다. 

 

 WebSecurityConfigurerAdapter 클래스가 SecurityFilterChain을 구성하는 클래스이다.

 

 스프링 시큐리티 필터는 굉장히 많다. 각기 다른 관심사를 가지고 자신의 관심사를 해결한다. 필터를 넣거나 뺄 수 있으며, 적용되는 순서도 조절할 수 있다.(이 떄 필터의 순서는 굉장히 중요하기 때문에 기본 필터들은 순서들이 어느정도 정해져있다.)

 

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests((requests) ->
                requests.antMatchers("/")
                        .permitAll()
                        .anyRequest()
                        .authenticated()
        );
        http.formLogin();
        http.httpBasic();
    }

 

 이 설정으로 SecurityFilterChain의 필터들이 정해진다는 사실을 알았다. @EnableWebSecurity(debug = true)이기 떄문에 필터 체인 실행 정보가 콘솔에 기록된다.

 

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  CsrfFilter
  LogoutFilter
  UsernamePasswordAuthenticationFilter
  DefaultLoginPageGeneratingFilter
  DefaultLogoutPageGeneratingFilter
  BasicAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

 

* 만약에 configure 내부의 필터 설정을 주석처리 한다면?

 

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //http.authorizeRequests((requests) ->
        //        requests.antMatchers("/")
        //                .permitAll()
        //                .anyRequest()
        //                .authenticated()
        //);
        //http.formLogin();
        //http.httpBasic();
    }

 

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  CsrfFilter
  LogoutFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
]

 

작동하는 필터의 갯수가 줄어들었다.

 

 

제외된 필터 목록은 다음과 같다.

 

Security filter chain: [
  UsernamePasswordAuthenticationFilter
  DefaultLoginPageGeneratingFilter
  DefaultLogoutPageGeneratingFilter
  BasicAuthenticationFilter
  FilterSecurityInterceptor
]

 

추가적으로 headers(), csrf(), logout(), requestCache()disable() 시키면 필터 체인에서 필터가 더 줄어든다.

 

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests((requests) ->
//                requests.antMatchers("/")
//                        .permitAll()
//                        .anyRequest()
//                        .authenticated()
//        );
//        http.formLogin();
//        http.httpBasic();
        http
                .headers().disable()
                .csrf().disable()
                .logout().disable()
                .requestCache().disable();
    }

 

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
]

 

 

* 다양한 필터 체인중에 경로 설정은 어떻게 하는가?

 

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**");
        http.authorizeRequests((requests) ->
                requests.antMatchers("/")
                        .permitAll()
                        .anyRequest()
                        .authenticated()
        );
        http.formLogin();
        http.httpBasic();
    }

 

antMatchers를 활용한다.

 

* 2개 이상의 필터 체인을 적용하고 싶다고 하면 어떻게 하면 되는가?

 

 시큐리티 필터 체인을 1개 더 생성하면 된다. 대신, 체인의 순서가 중요하드로 클래스 위에 @Order(1), @Order(2) 처럼 순서를 잘 정한다.

 

반응형