애플리케이션의 인증, 인가 등의 보안기능을 제공하는 스프링 하위 프로젝트 중 하나.
스프링 시큐리티의 동작구조
스프링 시큐리티는 서블릿 필터(Servlet Filter)를 기반으로 동작, DispatcherServlet 앞에 필터가 배치되어 있음
위 그림의 필터체인은 서블릿 컨테이너에서 관리하는 ApplicationFilterChain을 의미한다.
클라이언트에서 애플리케이션으로 요청을 보내면 서블릿 컨테이너는 URI를 확인해서 필터와 서블릿을 매핑한다.
스프링 시큐리티는 사용하고자 하는 필터체인을 서블릿 컨테이너의 필터 사이에서 동작하기위해 DelegatingFilterProxy를 사용
DelegatingFilterProxy는 서블릿 컨테이너의 생명주기와 스프링 애플리케이션 컨텍스트(Application Context) 사이에서 다리 역할을 수행하는 필터 구현체이다.
표준 서블릿 필터를 구현하고 있으며, 역할을 위임할 필터체인 프록시(FilterChainProxy)를 내부에 가지고 있다.
필터체인 프록시는 스프링부트 자동 설정에 의해 자동 생성된다.
필터체인 프록시는 스프링 시큐리티에서 제공하는 필터로서 보안 필터체인(SecurityFilterChain)을 통해 많은 보안 필터(Security Filter)를 사용할 수 있다.
필터체인 프록시에서 사용할 수 있는 보안 필터 체인은 List 형식으로 담을 수 있게 설정되어 있어 URI 패턴에 따라 특정 보안필터 체인을 선택해서 사용하게 된다.
보안 필터체인은 WebSecurityConfigurerAdapter 클래스를 상속받아 설정할 수 있다.
필터체인 프록시는 여러 보안 필터체인을 가질 수 있어, 여러 보안 필터체인을 만들기위해서는 WebSecurityConfigurerAdapter 클래스를 상속받는 클래스를 여러개 생성하면 된다. 이때, WebSecurityConfigurerAdapter 클래스에는 @Order 어노테이션을 통해 우선순위가 지정되어 있는데 2개 이상의 클래스를 생성했을 대 똑같은 설정으로 우선순위가 100이 설정되어 있으면 예외가 발생하기 때문에 상속받은 클래스에서 @Order 어노테이션을 지정해 순서를 지정하는것이 중요하다.
만약 별도의 설정이 없다면, 스프링시큐리티는 아래와 같이 SecurityFilterChain에서 사용하는 필터 중 UsernamePasswordAuthenticationFilter를 통해 인증을 처리한다.
위 그림의 인증 수행 과정을 설명하면
1. 클라이언트로부터 요청을 받으면 서블릿 필터에서 SecurityFilterChain으로 작업이 위임되고, 그 중 UsernamePasswordAuthenticationFilter(위 그림에서 AuthenticationFilter에 해당)에서 인증을 처리한다.
2. AuthenticationFilter는 요청 객체(HttpServletRequest)에서 username과 password를 추출해서 토큰을 생성
3. AuthenticationManager에게 토큰을 전달. AuthenticationManager는 인터페이스이며, 일반적으로 사용되는 구현체는 ProviderManager 이다.
4. ProviderManager는 인증을 위해 AuthenticationProvider로 토큰을 전달
5. AuthenticationProvider는 토큰의 정보를 UserDetailsService에 전달
6. UserDetailsService는 전달받은 정보를 통해 데이터베이스에서 일치하는 사용자를 찾아 UserDetails 객체를 생성
7. 생성된 UserDetails 객체는 AuthenticationProvider로 전달되며, 해당 Provider에서 인증을 수행하고 성공하게 되면 ProviderManager로 권한을 담은 토큰을 전달
8. ProviderManager는 검증된 토큰을 AuthenticationFilter로 전달
9. AuthenticationFilter는 검증된 SecuritycontexHolder에 있는 SecuritryContext에 저장
위 과정에서 사용된 UsernamePasswordAuthenticationfilter는 접근 권한을 확인하고 인증이 실패한 경우 로그인 폼이라는 화면을 보내는 역할을 수행한다.
'Spring Boot' 카테고리의 다른 글
JWT (0) | 2024.01.26 |
---|---|
front + backend 게시판 CRUD 구현 (1) (0) | 2023.10.19 |