공부하는 블로그
필터가 중복되는 문제 해결 본문
프로젝트에서 인증/인가를 사용하기 위해 JWT를 구현하면서 JWT 필터를 작성했다.
JWT 필터는
1. 요청 URI가 퍼블릭이라면 필터 통과
2. 아니라면 인증 헤더가 올바른지 확인
3. JWT 토큰 파싱, 검증
4. 인증 정보를 SecurityContext에 담고 필터를 통과
순서로 진행되게 로직이 구성돼있다.
private boolean isPublicUri(String uri) {
return uri.startsWith("퍼블릭URI");
}
if (isPublicUri(request.getRequestURI())) {
filterChain.doFilter(request, response);
return;
}
그리고 코드리뷰를 하다가 이 코드에서 두 가지 문제점이 제기되었다.
1. SecurityConfig, JwtFilter에 각각 퍼블릭 URI를 명시해줘야 해서 실수를 유발할 수 있음
2. JwtFilter에 퍼블릭 URI를 검증 로직이 필요한지 의문
@Bean
public WebSecurityCustomizer ignoringCustomizer() {
return (web) -> web.ignoring().requestMatchers("퍼블릭 URI");
}
그래서 더 나은 방법을 찾아보다가 팀원 분이 WebSecurity를 커스텀해서 특정 요청을 스프링 시큐리티 필터 체인에서 제외시킬 수 있는 기능을 알려주셨다. 여기 한 곳에서 퍼블릭 URI를 관리한다면 위에서 나왔던 두 문제를 해결 할 수 있을 것 같았다.
그렇게 JWT 필터에서 퍼블릭URI 검증 로직과 시큐리티 설정에서 .authorizeHttpRequests(auth -> auth.requestMatchers("퍼블릭URI")).permitAll() 를 잠시 주석처리하고 요청을 보내보았더니 여전히 JWT 필터를 거치고 있다는 것을 확인했다.
스프링 시큐리티 필터 체인이 아니라 서블릿 필터에 등록돼있는 것을 확인하고
혹시 필터가 중복으로 등록돼있어서 스프링 시큐리티 필터체인에서 제외돼도 필터를 타는 것이 아닌가해서 찾아보니 JWT 필터가 스프링 빈으로 등록돼있는 것이 원인이었다.
https://docs.spring.io/spring-boot/reference/web/servlet.html
Servlet Web Applications :: Spring Boot
If you want to build servlet-based web applications, you can take advantage of Spring Boot’s auto-configuration for Spring MVC or Jersey.
docs.spring.io
Any Servlet, Filter, or servlet *Listener instance that is a Spring bean is registered with the embedded container. This can be particularly convenient if you want to refer to a value from your application.properties during configuration. By default, if the context contains only a single Servlet, it is mapped to /. In the case of multiple servlet beans, the bean name is used as a path prefix. Filters map to /*. If convention-based mapping is not flexible enough, you can use the ServletRegistrationBean, FilterRegistrationBean, and ServletListenerRegistrationBean classes for complete control.
스프링 빈으로 등록된 서블릿, 필터, 리스너는 자동으로 내장 서블릿 컨테이너로 등록된다고 한다.
JWT 필터가 스프링 빈이기 때문에 자동으로 서블릿 필터에 등록이 됐던 것이다.
우리는 JWT 필터를 시큐리티 필터 체인에만 등록하고, 퍼블릭 URI 유무에 따라 필터 적용 여부를 제어하고 싶었다.
그래서 스프링 빈 등록을 해제한 뒤, 시큐리티 설정에만 추가하고 퍼블릭 요청을 다시 보내보았다.
의도대로 서블릿 필터 체인에서 JWT 필터가 제외되었고, 시큐리티 필터 체인이 동작하지 않아 요청이 바로 처리되는 것을 확인할 수 있었다.
결과적으로 필터 중복 문제를 해결함으로써 JWT 필터는 JWT를 이용한 인증/인가 로직에만 집중할 수 있게 됐고,
퍼블릭 URI를 한 곳에서 관리할 수 있게 되었다.
추가로 참고한 글
WebSecurityCustomizer (spring-security-docs 6.4.3 API)
docs.spring.io
https://m42-orion.tistory.com/155
[Spring Security] FilterChain에 대해
이 글은 공부를 하면서 알게 된 내용들을 기록하는 글 입니다. 오류나 고쳐야 할 사항들이 있다면 지적 부탁드립니다!✅ Filter Chain이란 무엇인가?Filter chain에 대해 알아보기 전에 `Filter`에 대해
m42-orion.tistory.com
'트러블슈팅' 카테고리의 다른 글
DB 인덱스는 만능일까? (0) | 2024.10.18 |
---|---|
AWS 관련 기능 로컬에서 테스트 할 때 지역을 못 찾는 경우 (2) | 2024.10.10 |