반응형
이 포스트는 데어 프로그래밍님의 유튜브 강의를 듣고 나서 정리한 글입니다.
Spring Security Filter 구조
필터를 등록하기 전 SpringFilterChain
구조에 대해서 먼저 알면 좋습니다.
Filter를 생성해보자
public class MyFilter1 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter 1");
filterChain.doFilter(servletRequest, servletResponse); // 다음 필터로 넘어가라는 의미
}
}
- Servlet 아래에 있는 Filter 인터페이스를 구현해주면 됩니다.
- 해당 필터에서 처리하고 다시 다음 필터로 넘겨주는
doFilter
호출을 해줘야합니다.
Filter 등록
addFilter(Filter filter)
addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)
addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)
addFilter
http.addFilter(new MyFilter1());
에러 메세지:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: The Filter class me.iseunghan.jwttutorial.filter.MyFilter1 does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.
MyFilter1은 SpringSecurityFilterChain에 등록되지 않았으니 등록하고 싶으면 addFilterBefore or addFilterAfter
를 사용하라!
사용해봅시다.
addFilterBefore
http.addFilterBefore(new MyFilter1(), UsernamePasswordAuthenticationFilter.class);
UsernamePasswordAuthenticationFilter 직전에 MyFilter가 걸리도록 합니다.
addFilterBefore
http.addFilterAfter(new MyFilter1(), UsernamePasswordAuthenticationFilter.class);
UsernamePasswordAuthenticationFilter 이후에 MyFilter가 걸리도록 합니다.
FilterConfig 생성
굳이 SecurityConfg에서 추가하지 말고, 따로 FilterConfig를 생성하여 등록해보겠습니다.
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter1> filter1() {
FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
bean.addUrlPatterns("/*"); // 모든 요청에 대해서 필터 적용
bean.setOrder(0); // 낮은 숫자일수록 우선순위
return bean;
}
}
FilterRegistrationBean
을 생성하여 MyFilter1을 빈으로 등록시켜주면 끝입니다.- urlPatterns
"/**"
가 아닌 점 주의!
- urlPatterns
필터가 언제 실행되는가?
SpringSecurityFilter가 먼저 실행될까요? 아니면 우리가 생성해준 MyFilter가 먼저 실행될까요?
테스트 환경
- MyFilter1 과 MyFilter2를 생성
- MyFilter1은 FilterConfig에 등록! (위 코드와 동일 : 우선순위 0으로 설정)
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter1> filter1() {
...
bean.setOrder(0); // 낮은 숫자일수록 우선순위
..
- MyFilter2는 SecurityConfig에 등록! (Username..Filter 이전에 실행되도록 설정)
http.addFilterBefore(new MyFilter2(), UsernamePasswordAuthenticationFilter.class)
실행 결과
Filter2가 Filter1 보다 먼저 실행되었다.
우리가 생성한 필터보다 SpringSecurityFilter가 가장 먼저 실행된다.
SpringSecurityFilter보다(또는 특정 필터 이전에 또는 이후에) 먼저 실행되게 하려면?
SpringSecurity 설정에서 필터를 등록해준다.
addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)
addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)
반응형