Spring - Filter, Interceptor

Tadap·2023년 12월 5일
0

Spring Security

목록 보기
7/7

스프링 시큐리티를 공부하면서 쓴 필터와 인터셉터를 실제로 사용해보고 한 정리이다.

필터

스프링의 Dispatcher Servlet에 요청이 전달되기 전 후 모든 요청에 대한 처리 기능을 제공

  1. init - 필터 초기화 하는 매서드
  2. doFilter - 실제 필터 처리를 하는 매서드
  3. destroy - 필터를 사용하지 않을때 자원 반환을 위한 매서드

3가지의 매서드로 이루어져 있다.

인터셉터

스프링에서 제공하는 기술로 DispatcherServlet이 Controller를 호출 하기 전 요청, 응답을 참조,가공 가능한 기능을 제공한다.
스프링에서 실행되기 때문에 모든 스프링의 기술을 사용 가능하다.

  1. preHandle - 컨트롤러 호출 전 실행
  2. postHandle - 컨트롤러 호출 후 실행
  3. afterCompletion - 최종 결과를 생성 후 실행, 실행시 사용한 리소스 반환시 사용

차이점

대상필터인터셉터
관리되는 컨테이너서블릿 컨테이너스프링 컨테이너
스프링의 예외처리 여부XO
Request/Response조작 가능 여부OX
추천 용도공통된 보안 작업, 인코딩, Spring과 분리되어야 하는 기능세부적인 보안 작업, 로깅,감사, Controller로 가기 전 데이터 가공

나의 케이스

현재 진행중인 프로젝트에서 아래와 같은 상황이다.

Member 테이블에서는 Role과 Security를 통해 관리자 / 회원 / 비회원을 구분한다.

여기서 추가적으로 Club의 데이터를 요청할 때 ClubMember의 권한에 따라 요청을 추가해 줘야 하는 상황이다.

해결방법

1. Filter로 처리

필터로 처리를 하면서 Repository, 혹은 Service계층에 접근을 해서 Role 을 가져와 SecurityContext에 넣어주는 방법을 사용 가능하다.
이렇게 하면 @PreAuthorize("hasAnyAuthority('ROLE_CLUB_HOST', 'ROLE_CLUB_ADMIN') and hasAnyAuthority('ROLE_ADMIN', 'ROLE_USER')") 이런식으로 한번에 처리가 가능하다.
아니면 SecurityConfig에서 Member와 관련된 Role 처리만 하고 특정 메서드에서만 처리도 가능하다.

하지만 관심사의 분리 원칙을 위배해야 한다.
필터에서 Service, Repository계층에 접근을 하기 때문에 지양해야 한다.

2. Interceptor로 처리

  1. 인터셉터에서 SecurityContext에 Role을 추가해주기 (실패)
    시도를 하였으나 SecurityContext에 있는 데이터는 인터셉터 이전에 캐싱을 하고, 그 데이터를 컨트롤러에서 @AuthenticationPrincipal 로 받는다고 한다. 아무리 인터셉터에서 데이터를 넣어줘도 컨트롤러에 닿지 않는다... 직접 꺼내서 쓰는건 코드가 더러워 져서 이 방법은 폐기했다.

  2. 인터셉터에서 특정 UrlPattern에 대한 요청만 인터셉터로 처리
    인터셉터에서 특정 패턴에 대한 처리를 하면 간편하게 처리가 가능하다. 해당 권한이 없으면 -> 인터셉터 작동 이런식으로 사용 가능하다.
    하지만 현재 나의 경우에는 POST, GET같은 Method와 더불어 URLPattern 도 맞춰줘야 하기 때문에 UrlPattern을 따로 관리해 주는것은 매우 귀찮은 일이다.

결론

결국 인터셉터를 통해 처리하기로 하였다.
가장 큰 이유는 UrlPattern을 2중으로 관리하면 너무 불편할것 같다는 팀원의 생각이었다.
나는 Servlet에서 Spring의 Repository와 Service에 접근은 아니라고 생각해 2-1번 방법을 이용했으나 위와 같은 이유료 실패 하였고
따라서 자연스럽게 필터 선택지만 남게 되었고 필터를 통해 구현하게 되었다.

항상 코드에는 정답이 없다는게 매력이고 재미 포인트라고 생각한다. 덕분에 머리속에서 희미하게 지워지던 기술을 다시 재습득하게 된 기회가 되었다

참고사이트

0개의 댓글