[Spring Security6] 내부 흐름
브라우저는 HTTP 프로토콜을 기반으로 서버에게 요청을 보낸다.
자바로 작성한 애플리케이션은 HTTP 프로토콜을 기반으로 사용자의 요청을 처리하는데...
자바 코드는 HTTP 프로토콜을 이해할 수 없다.
따라서 브라우저와 자바로 작성한 애플리케이션을 이어주는 다리가 필요하다.
스프링은 이 다리로 서블릿을 사용한다.
서블릿은 HTTP 프로토콜을 이해하고 처리할 수 있는 자바 코드로 생각하면 된다.
사용자의 HTTP 요청이 스프링으로 구축된 서버에 도착하면 가장 먼저 웹 애플리케이션 서버인 Tomcat이 요청을 받는다.
이후 Tomcat은 서블릿에게 HTTP 요청을 전달하고 서블릿은 요청을 처리한다.
처리된 요청은 Tomcat에게 전달되고, Tomcat은 사용자에게 HTTP 응답을 제공한다.
Tomcat은 서블릿을 관리하는 컨테이너이고, 서블릿은 클라이언트의 요청을 처리하는 컴포넌트이다.
Tomcat이 클라이언트의 요청을 받은 후 서블릿에게 전달하는데, 서블릿 필터가 요청을 먼저 받아 로깅, 인증 등 검사를 수행한다.
스프링 시큐리티는 시큐리티 필터를 사용한다.
시큐리티 필터는 여러 종류가 있고, 모든 요청을 가로챌 수 있다.
기본적으로 서블릿 필터를 사용해 보안 기능을 구현하지만 일반적인 서블릿 필터와는 조금 다르게 동작한다.
서블릿 필터 개념을 확장한 FilterChainProxy 필터를 사용해 보안 관련 필터를 관리하고, 필터들의 실행 순서를 세밀하게 조정할 수 있다.
아래는 시큐리티의 주요 구성 요소이다.
Spring Security Filters : 모든 요청을 가로채고 요청이 인증이 필요한 부분인지 확인한다. 인증이 필요하다면 로그인 페이지로 이동시키거나 에러 페이지를 보여준다.
Authentication : HTTP 요청으로부터 아이디와 비밀번호를 추출하고 권한 정보를 포함하는 Authentication 객체를 만든다.
AuthenticationManager : 필터로부터 요청받고 사용자를 검증한다. 검증 과정에서 Provider 목록을 사용한다.
AuthenticationProvider : 유저를 검증하기 위한 로직을 포함하고 있다.
UserDetailManager/Service : 데이터베이스와 연결해 사용자 관련 정보를 다룬다.
AuthenticationProvider의 authenticate 메서드의 구현에 따라 사용하지 않을 수도 있다.
Manager는 여러 Service를 관리하고 조장하는 객체라고 생각하면 된다.
PasswordEncoder : 비밀번호를 인코딩하고 해싱하는 작업을 수행한다.
SecurityContext : 현재의 보안 정보를 쓰레드로컬 방식으로 저장한다. HTTP 세션을 통해 Context를 저장하고 복원할 수 있도록 SecurityContextPersistenceFilter를 제공하는데, 이 필터는 HTTP 요청이 들어오면 HTTP 세션에서 SecurityContext를 찾아 쓰레드로컬에 저장한다.
SecurityContext는 Authentication 객체를 포함하고 세션을 통해 유지되고 관리된다.
SecurityContext를 저장하고 가져올 때는 SecurityContextHolder 클래스를 사용한다. (쓰레드 로컬을 사용한다)
SecurityContextHolder를 물컵으로, SecurityContext를 컵으로 생각하면 된다.
HTTP 세션의 식별자는 JSESSIONID 쿠키를 통해 관리되며, 이 쿠키를 통해 서버는 HTTP 세션을 식별하고 세션에 저장된 SecurityContext를 사용해 인증된 사용자의 상태를 여러 요청에 걸쳐 유지한다.
100명의 사용자가 접속하면 100개의 세션 정보가 서버에 저장되고 100개의 세션ID가 생성된다.
세션은 고유한 세션ID로 식별되니 서버는 클라이언트의 상태를 별도로 유지한다.
시큐리티의 필터들은 필요에 따라 위의 구성 요소들을 사용한다.
시큐리티가 제공하는 코드를 살펴보자.
public class AuthorizationFilter extends GenericFilterBean { ... }
해당 요청이 public 한 요청인지 secure 한 요청인지 판단하는 필터이다.
public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { ... }
로그인 페이지를 만들어주는 필터이다.
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { ... }
아이디와 비밀번호로 인증을 시도하는 필터이다.
내부적으로 ProviderManager를 사용해 인증 과정 중 하나의 AuthenticationProvider 가 성공하면 인증을 종료한다.
이 외에도 다양한 필터가 있으니.. 스프링을 디버깅 모드로 실행하고 어떤 필터가 작동하는지 직접 확인하면서 공부해보자.
'Spring > Spring Security' 카테고리의 다른 글
[Spring Security6] Authorization과 Filter (0) | 2023.08.09 |
---|---|
[Spring Security6] CORS, CSRF (0) | 2023.08.08 |
[Spring Security6] 사용자 인증 (0) | 2023.08.06 |
[Spring Security6] Password Encoder (0) | 2023.08.05 |
[Spring Security6] 주요 구성요소 (0) | 2023.08.04 |
댓글
이 글 공유하기
다른 글
-
[Spring Security6] CORS, CSRF
[Spring Security6] CORS, CSRF
2023.08.08 -
[Spring Security6] 사용자 인증
[Spring Security6] 사용자 인증
2023.08.06 -
[Spring Security6] Password Encoder
[Spring Security6] Password Encoder
2023.08.05 -
[Spring Security6] 주요 구성요소
[Spring Security6] 주요 구성요소
2023.08.04