이번 주는 스프링 시큐리티 적용을 하면서 수많은 삽질을 겪게 되었습니다. 트러블슈팅 경험을 정리하기 전에 먼저 스프링 시큐리티의 기초를 먼저 정리해봅시다!
Servlet 이란?
Servlet 클래스 관계도
- Servlet은 인터페이스이며, 이를 상속받은 것이 GenericServlet (추상클래스)입니다.
- GenericServlet은 다시 상속받은 것이 HttpServlet (추상클래스)입니다.
- HttpServlet의 service 메소드는 HttpServletRequest를 인자로 받습니다. 이 때의 HttpServletRequest는 ServletRequest 인터페이스의 구현체입니다.
HttpServletRequest 의 역할은 결국엔 서블릿 컨테이너에서 HttpServlet의 service(HttpServletRequest req, HttpServletResponse resp) 메소드를 수행할 수 있도록 파라미터를 넘겨주기 위함입니다.
HttpServlet 의 service() 메소드를 보면 이를 확인할 수 있습니다.
Servlet 과 Filter의 관계
그렇다면 Sevlet과 필터의 관계는 어떻게 될까요?
FilterChain 인터페이스의 구현체인 ApplicationFilterChain
의 설명을 확인해보면 서블릿 생성 후(init) Filter 를 순서대로 모두 실행하고 service() 메소드가 실행됩니다.
정리하자면 순서는 다음과 같습니다.
- 서블릿 컨테이너에서 서블릿을 생성할 때 init()
- 모든 filter 를 거침
- 마지막 필터 후 서블릿의 service() 메소드 사용
Spring Security
스프링 시큐리티에서 쓰이는 필터가 서블릿의 스펙이라는 것을 감안하면 이상한 점이 보입니다. 분명 빈은 스프링 컨테이너에 등록되는 것인데 어떻게 서블릿 컨테이너에서 빈으로 등록된 필터를 가져오는 것일까요? 여기서 등장하는 것이 DelegatingFilterProxy
입니다.
중요한 점은 스프링의 ContextLoaderListener
은 필터 인스턴스가 먼저 등록되고 나서야 스프링 컨테이너의 빈 등록이 시작된다는 점입니다. 그렇다면 스프링 빈 필터를 쓰는 경우 필터 등록을 해야하는 시점에 빈 등록이 완료되지 않았다는 것입니다. 다행히도 DelagatingFilterProxy
에서 필터 등록을 지연시켜주기 때문에 빈 등록을 하고 필터 등록을 할 수 있습니다다.
DelatingFilterProxy 안에는 FilterChainProxy
가 존재합니다. 이는 스프링 빈이기 때문에 DelagatingFilterProxy 안에 감싸져있습니다.
DelegatingFilterProxy 안에는 FilterChainProxy가 존재하며, 이는 스프링 빈이기 때문에 DelegatingFilterProxy 안에 감싸져 있습니다. FilterChainProxy에서부터 스프링 시큐리티 기능이 시작되며, SecurityFilterChain 여러 개가 등록되어 URL에 따라 어떤 체인을 실행시킬지 결정합니다.
다음 글에서는 스프링 시큐리티 삽질 q&a 컨텐츠로 돌아오도록 하겠습니다:)
'☘️Spring' 카테고리의 다른 글
[Spring] 스프링 시큐리티 인증/인가 및 에러 삽질 (3) | 2024.02.04 |
---|---|
[Spring] JPA N+1 문제 해결 (35) | 2023.10.30 |
[Spring] MockMvcTest vs End-to-End Tests (1) | 2023.10.26 |
[Spring] web mvc 코드로 이해하기 (0) | 2023.09.02 |
[Spring] 의존관계 자동/수동 주입 (0) | 2023.07.09 |