필터 구현

  • 요청을 수신하고 로직을 실행한 뒤 다음 체인의 필터에 요청을 위임한다.

  • 인증을 보강하기 위해 OTP를 ㅊ ㅜ가하거나 로깅과 관련된 기능 등을 추가할 수 있다.

9.1. 스프링 시큐리티 아키텍처의 필터 구현

  • Filter 인터페이스를 구현하고 doFilter() 메서드를 재정의한다.

    • ServletRequest

      • HTTP 요청을 나타낸다.

    • ServletResponse

      • HTTP 응답을 나타낸다.

    • FilterChain

      • 체인의 다음 필터로 요청을 전달한다.

      • 필터 체인: 작동 순서가 정의된 필터의 모음

  • 기본적으로 구현된 필터

    • BasicAuthenticationFilter

      • HTTP Basic 인증을 처리한다.

      • httpBasic()을 호출하면 필터 체인에 추가된다.

    • CsrfFilter

      • 사이트 간 요청 위조를 처리한다.

    • CorsFilter

      • 교차 출처 리소스 공유 권한 부여 규칙을 처리한다.

  • 여러 필터가 같은 위치에 있으면 호출되는 순서는 랜덤이다.

9.2. 체인에서 기존 필터 앞에 필터 추가

public class RequestValidationFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 로직 구현
    }
}

@Configuration
public class ProjectConfig {

    ...

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new RequestValidationFilter(), BasicAuthenticationFilter.class)
                .authorizeHttpRequests(requestMatcherRegistry -> requestMatcherRegistry.anyRequest().permitAll());

        return http.build();
    }
}
  • 필터에 로직을 구현하고 체인에 추가한다.

9.3. 체인에서 기존 필터 뒤에 필터 추가


@Configuration
public class ProjectConfig {

    ...

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new RequestValidationFilter(), BasicAuthenticationFilter.class)
                .addFilterAfter(new AuthenticationLoggingFilter(), BasicAuthenticationFilter.class)
                .authorizeHttpRequests(requestMatcherRegistry -> requestMatcherRegistry.anyRequest().permitAll());

        return http.build();
    }
}

9.4. 필터 체인의 다른 필터 위치에 필터 추가

  • 기존 필터에 다른 필터를 적용하면 대체되는 것이 아니라 순서를 보장하지 않는 상태에서 실행된다.

  • 인증 키는 속성 파일이 아니라 비밀 볼트를 이용한다.


@Configuration
public class ProjectConfig {

    ...

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new RequestValidationFilter(), BasicAuthenticationFilter.class)
                .addFilterAfter(new AuthenticationLoggingFilter(), BasicAuthenticationFilter.class)
                .addFilterAt(new StaticKeyAuthenticationFilter(), BasicAuthenticationFilter.class)
                .authorizeHttpRequests(requestMatcherRegistry -> requestMatcherRegistry.anyRequest().permitAll());

        return http.build();
    }
}
@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
  • UserDetailsService가 필요하지 않다면 비활성화 할 수 있다.

9.5. 스프링 시큐리티가 제공하는 필터 구현

  • GenericFilterBean

    • web.xml에 정의한 초기화 매개 변수를 이용할 수 있다.

  • OncePerRequestFilter

    • GenericFilterBean을 확장한 더 유용한 클래스

    • doFilter()가 한 번만 실행되는 것을 보장한다.

    • HTTP 요청만 지원해서 request, response 값을 형변환 할 필요가 없다.

    • shouldNotFilter()로 적용되지 않는 경우를 재정의할 수 있다.

    • 비동기 요청이나 오류 발송 요청에는 적용되지 않는다.

      • 이떄는 shouldNotFilterAsyncDispatch(), shouldNotFilterErrorDispatch()를 재정의한다.

  • 스프링이 제공하는 클래스를 굳이 쓸 필요 없는 간단한 사례라면 안 써도 된다.

Last updated

Was this helpful?