AuthenticationFilter 어떤 필터를 상속받을 것인가?

meong·2023년 8월 25일
4

Intro

프로젝트 Security & JWT 설정을 하려던 중...
팀원 한 분이 던진 질문에 저는 필터 늪에 빠지게 됐습니다 !

  • 🧐: jwt 필터 UsernamePasswordAuthenticationFilter 상속 받아서 쓰실 예정인가요?
  • 🙋‍♀️: 강사님 코드는 BasicAuthenticationFilter 네요?
  • 🧐: 필터 아무거나 써도 되긴 하는데 전 OncePerRequestFilter 썼어요

왜 필터 질문을 하셨으며, 왜 OncePerRequestFilter를 선택하셨는지!
너무 궁금해서 바로 찾아봤고
결론적으로 저도 OncePerRequestFilter를 상속받기로 했습니다

* 저의 개인적인 생각&의견일 뿐 정답은 아닙니다 🥲 그냥 가볍게 읽어주세요


왜 Filter를 커스텀 하려는가?

저희는 클라이언트(리엑트 서버)에서 json으로 Username/Password를 전달받으며,
로그인 이후에는 발급한 jwt 토큰으로 사용자를 인증하려고 합니다

때문에 시큐리티에서 Username/Password 기반 인증을 수행하는
UsernamePasswordAuthenticationFilter, BasicAuthenticationFilter를 비활성화 하기 위해
SecurityConfig에서 다음과 같이 설정해줬습니다

// 5. form 로그인 해제 (UsernamePasswordAuthenticationFilter 비활성화)
http.formLogin().disable();

// 6. username, password 헤더 로그인 방식 해제 (BasicAuthenticationFilter 비활성화)
http.httpBasic().disable();

프로젝트 구조에 맞게, 초기 로그인 및 토큰 발급은 Controller에서
json으로 Username/Password 값을 요청받아 수행하고

이 후 클라이언트 요청마다 들어오는 토큰으로 사용자를 인증하도록
필터(JwtAuthenticationFilter)를 커스텀하여 끼워주면 됩니다!

왜 OncePerRequestFilter 상속인가?

앞에서 UsernamePasswordAuthenticationFilter, BasicAuthenticationFilter는
저희 프로젝트 구조와 맞지 않다고 생각해서 제거했습니다.

그런데 이 필터들 중 하나를 다시 상속받는다는 게 마음 한구석이 찝찝한...(??)
이 찝찝함을 없애줄 명분이 필요했습니다 😉

필터 후보

1. UsernamePasswordAuthenticationFilter

AbstractAuthenticationProcessingFilter의 하위 클래스로
주로 웹 폼 기반의 로그인 처리를 다루는 데 사용됩니다.
사용자가 로그인 폼에 입력한 사용자명과 비밀번호를 받아와 인증을 시도합니다.

JWT 토큰 인증 과정과 겹치는 부분이 전혀 없었습니다 

2. BasicAuthenticationFilter

OncePerRequestFilter의 하위 클래스로
HTTP Basic 인증을 처리하는 필터입니다.
Basic 인증은 클라이언트가 Base64로 인코딩한 사용자명과 비밀번호를
"Authorization" 헤더에 포함시켜 요청을 보내는 방식 입니다.

💡 유력 후보 발견 ?

"Authorization" 헤더에 있는 값으로 인증을 시도한다는 점에서 JWT용 필터와 겹치는 부분이 있다고 생각했습니다. 
하지만 기존에 HTTP Basic 인증을 위한 필터였다는 점, 헤더는 같지만 담기는 값은 다르다는 점을 고려해서 
'그렇다면 상위클래스인 OncePerRequestFilter를 쓰는건 어떨까?' 생각했습니다

3. GenericFilterBean

주로 단순한 필터 동작을 정의할 때 사용되며, Spring의 빈 라이프사이클과 통합되어
스프링 빈으로 등록된 필터가 필요한 초기화나 종료 작업을 수행할 수 있도록 지원합니다.

각 요청마다 필터가 실행되며, 중복 호출을 관리하지 않아 요청마다 여러 번 실행될 수 있습니다

이 클래스를 상속하여 커스텀한 글들이 보여 찾아봤지만 중복 호출이 될 수 있다는 점이 아쉬웠습니다.

4. OncePerRequestFilter

GenericFilterBean의 하위클래스로
요청당 한 번만 실행되는 필터를 생성하기 위해 사용됩니다.

이 클래스는 요청이 처리되는 동안 한 번만 실행되도록 보장해주는 메커니즘을 제공합니다.
이는 필터 체인에서 필터의 중복 실행을 방지하는 데 도움이 됩니다.

⛳️ 결정

GenericFilterBean의 기능을 상속받으면서, 추가적으로 중복 호출을 방지 기능이 있는 필터였습니다!
필터의 목적이 JWT 인증과 크게 동떨어지는 부분(폼 로그인, HTTP Basic 인증용 필터와 같은)이 없고
중복 호출 방지 까지 되기 때문에 OncePerRequestFilter가 가장 적합하다고 생각했습니다

마치며

사실 어떤 필터를 상속하더라도 결과에는 큰 차이가 없을 것 같습니다
그렇치만 상속 받는 클래스가 어떤 특성을 가지고 있는지
이렇게 따져보는 것도 그 기술을 이해하는데 더 도움이 되는 것 같습니다

좋은 질문 해주신 팀원 님께 압도적 감사...! 🙏🏻

profile
새싹 개발자

0개의 댓글