[ SpringBoot ] FilterChain

devK08·2024년 10월 29일

SpringBoot

목록 보기
2/9
post-thumbnail

Spring Security에서 지원해주는 FilterChain이다.
Client에서 톰캣에 있는 내장 필터를 거치고 Spring Security로 들어간다.
그리고 이 DelegatingFilterProxy에서 Spring Security로 오는 클라이언트의 요청을 최초로 받게 된다.
그래서 DelegatingFilterProxy을 SpringBoot Security에서 기본적으로 만든 필터나, 우리가 만든 CustomFilter들도 거칠 수 있게 해준다.

Security FilterChain에서 커스텀 필터 설정하기

@Configuration // 컴포넌트로 Bean 등록
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final ObjectMapper objectMapper;

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain FilterChain(HttpSecurity http, AuthenticationConfiguration authenticationConfiguration) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .formLogin(AbstractHttpConfigurer::disable)
                .httpBasic(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests((auth) -> auth
                        .requestMatchers(HttpMethod.GET, "/community/words/**").permitAll()
                        .requestMatchers(HttpMethod.GET, "/community/comments/**").permitAll()
                        .requestMatchers(HttpMethod.GET, "/community/wordlists/**").permitAll()
                        .requestMatchers(HttpMethod.POST, "/user/login").permitAll()
                        .requestMatchers(HttpMethod.POST, "/user/register").permitAll()
                        .requestMatchers(HttpMethod.GET, "/user/profile/**").permitAll()
                        .requestMatchers("/community/words/**").hasAnyRole("USER", "ADMIN")
                        .requestMatchers("/community/comments/**").hasAnyRole("USER", "ADMIN")
                        .requestMatchers(HttpMethod.GET, "/user/logout").hasAnyRole("USER", "ADMIN")
                        .requestMatchers(HttpMethod.PUT, "/user/update").hasAnyRole("USER", "ADMIN")
                        .requestMatchers(HttpMethod.DELETE, "/user/delete").hasAnyRole("USER", "ADMIN")
                        .requestMatchers(HttpMethod.POST, "/user/report").hasAnyRole("USER", "ADMIN")
                        .requestMatchers("/admin/**").hasAnyRole( "ADMIN")
                        .anyRequest().denyAll()
                )
                .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(new LoginFilter(authenticationManager(authenticationConfiguration), objectMapper), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

이것처럼 .addFilterBefore / .addFilterAt / .addFilterAfter로 커스텀 필터를 추가해줄 수 있다.
예시
.addFilterBefore(실행할 필터, 기존필터) : 기존필터 전에 실행할 필터를 삽입
.addFilterAt(실행할필터, 기존필터) : 기존필터 대신에 실행할 필터를 대체
.addFilterAfter(실행할필터, 기존필터) : 기존필터 후에 실행할 필터를 삽입

그리고 보통의 필터는 OncePerRequestFilter를 상속받아 생성한다. 그리고 doFilterInternal 메소드를 통해 Filter에 들어가면 실행할 함수를 설정한다. 그리고 만약에 UsernamePasswordAuthentication이나 LogoutFilter같은 SpringBoot Security에 있는 기존의 필터를 대신해서 사용하려면 이런 것들을 상속받아서 기존 필터들의 함수들을 오버라이딩해서 구성한다.
그리고 모든 검증절차가 끝난다면, doFilter함수를 실행시켜서 다음 필터를 실행시키도록 한다.

profile
안녕하세요. 개발자 지망 고등학생입니다.

0개의 댓글