Spring에서 말하는 스프링 시큐리티는 다음과 같다.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.
인증과 인가를 제공하는데 초점을 맞춘 프레임워크라고 소개하고 있다.
일반적으로 가장 먼저 작업하는 부분이 사용자 관리 부분으로, 가볍게는 회원가입부터 로그인, 로그아웃, 세션 관리, 권한 관리까지 온라인 플랫폼에 맞춰 다양하게 작업되는 인가 & 보안 기능은 개발자에게 많은 시간을 요구한다.
Spring 생태계 내에서 이러한 요구사항을 효과적으로 지원하기 위해 개발된 것이 Spring Security로, 개발자들이 보안 관련 기능을 효율적이고 신속하게 구현할 수 있도록 도와준다.
일단 시큐리티 작동원리에 대해서 알아보기전에 몇가지 보안 관련 단어를 짚고 가자.
이름 | 설명 |
---|---|
인증 (Authenticate) | 접근하려는 유저가 누구인지 확인하는 절차 EX) 나 이런 사람이다 |
인가 (Authorization) | 인증된 사용자에 대해서 권한을 확인하고 허락하는 것 |
접근 주체 (Principal) | 보호된 대상에 접근하는 유저 |
비밀번호 (Credential) | 대상에 접근하는 유저의 비밀번호 |
Spring Security 에서는 이러한 인증, 인가를 위해 Principal 을 아이디로 Credential 을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.
웹 인증과 인가를 편하게 구현하기 위한 특징이라고 보면 됨
일반적인 웹 환경에서 브라우저가 서버에게 요청을 보내게 되면 DispatcherServlet이 요청을 받기 이전에 많은 SevletFilter들을 거치게 된다.
이 부분부터 짚고 가보자. 등장인물 이름이 좀 비슷하니 잘 보삼
스프링 시큐리티는 서블릿의 필터를 기반으로 동작한다.
그런데, 하나 이상의 필터가 포함된다면, 클라이언트에서 보낸 요청이 서블릿으로 전달되기 전에 필터를 거치게 된다.
클라이언트가 애플리케이션에 하나의 요청을 보내면, 컨테이너는 하나의 필터 체인(FilterChain)을 생성한다.
필터 체인에는 필터와 서블릿이 들어 있다.
필터 체인 내부의 필터는 말 그대로 '필터'의 역할을 한다.
클라이언트에서 보낸 요청이 다음 필터나 서블릿에 전달되지 않도록 걸러낼 수 있다.
사용자의 요청이 서블릿에 전달되어 자원에 접근하기 전에, 스프링 시큐리티는 필터의 생명주기를 이용해서 인증과 권한 작업을 수행한다.
그런데, 서블릿과 스프링의 컨텍스트는 엄연히 다르다.
서블릿은 톰캣과 같은 WAS 단에서 동작하며 모든 웹 요청을 먼저 처리한다. 앞선 필터의 과정을 모두 거치고 난 다음에야 요청은 스프링 컨텍스트로 넘어온다. 다시말하면, 서블릿 컨테이너는 스프링 컨테이너의 빈을 인식할 수 없으므로, 필터에서는 스프링의 기능을 사용할 수 없다는 말이다.
필터에서도 스프링 기능을 사용하기 위해 위임(delegation)으로 이 부분을 극뽁했다.
스프링 시큐리티는 프로그램이 실행될 때 Filter chain에 하나의 필터를 추가한다.
이 필터가 DelegatingFilterProxy 이다. DelegatingFilterProxy는 서블릿 매커니즘을 통해 서블릿의 필터로 등록될 수 있으며 스프링에 등록된 빈을 가져와 의존성을 주입할 수 있다.
DelegatingFilterProxy에서는 서블릿 필터에서 받은 요청과 응답을 스프링 빈으로 등록된 필터로 전달한다. springSecurityFilterChain 이름으로 생성된 빈을 ApplicationContext에서 찾아 요청을 위임한다.
실제로 보안 처리는 하지 않고 위임만 하는 Servlet Filter다. 그냥 서블릿이랑 스프링의 다리 역할이구나~하고 이해하고 넘어가자.
FilterChainProxy는 springSecurityFilterChain의 이름으로 등록된 필터 빈이다. DelegatingFilterProxy에서 요청을 위임받는 놈이 얘다.
FilterChainProxy는 DelegatingFilterProxy를 통해 받은 요청과 응답을 SecurityFilterChain에 전달하여 이 빈 안에 있는 여러 보안 필터를 실행해 보안작업을 처리하는 역할을 한다.
DelegatingFilterProxy 에서 바로 SecurityFilterChain 을 실행시킬 수 있지만 중간에 FilterChainProxy 를 둔 이유 ?
➡️ 서블릿을 지원하는 시작점 역할을 하기 위함이다. 이를 통해 서블릿에서 문제가 발생하는 경우 FilterChainProxy 의 문제라는 걸 알 수 있다.
또한, FilterChainProxy 에서 어떤 체인에게 작업을 위임할지도 결정할 수 있음
-> Spring Security의 Filter를 사용하기 위한 진입점이라고 이해하자!
SecurityFilterChain은 인증을 처리하는 여러 개의 시큐리티 필터를 담는 필터 체인이다.
FilterChainProxy를 통해 서블릿 필터와 연결되고 어떤 시큐리티 필터를 통해 인증을 수행할지 결정하는 역할을 한다.
여러 개의 SecurityFilterChain 을 구성하여 매칭되는 URL 에 따라 다른 SecurityFilterChain 이 사용되도록 할 수 있다.
요청을 스프링 시큐리티 매커니즘에 따라 처리하는 필터다.
앞에서 본 DelegatingFilterProxy와 FilterChainProxy가 서블릿과 스프링과의 연결을 담당했다면, Security Filter는 시큐리티의 핵심 기능을 수행하는 지점이다.