이번에는 Spring Security가 지원하는 Authentication 중 하나인, Form Login의 구조에 대해 알아보겠습니다.
Spring Security는 HTML form 태그를 사용한 ID/PW 기반 인증을 지원합니다.
그럼 본격적으로 Form Login이 동작하는 구조에 대해 알아볼까요?
로그인 페이지로 Redirect
‘인증되지 않은 사용자’가 ‘인증이 필요한 리소스’에 접근할 때, Spring Security는 로그인 페이지로 Redirect 해줍니다.
먼저 이것이 어떻게 이루어지는지 살펴보겠습니다.
절차
- ‘인증되지 않은 사용자’가 ‘인증이 필요한 리소스’를 요청합니다.
-
FilterChainProxy
가 이 요청을 처리할SecurityFilterChain
을 호출합니다.
그리고 해당SecurityFilterChain
에 속한FilterSecurityInterceptor
라는 필터가 가장 먼저 실행됩니다.
이 필터에 의해AccessDeniedException
예외가 던져집니다.FilterChainProxy
와SecurityFilterChain
에 대해서는 이전 게시글에서 설명했습니다.
필요하다면 이 게시글을 참고하세요! -
던져진
AccessDeniedException
예외가ExceptionTranslationFilter
에 의해 catch 됩니다.
그리고 관련된AuthenticationEntryPoint
를 사용해서 클라이언트를 Redirect 시킵니다. 이때 사용되는AuthenticationEntryPoint
의 구현체는LoginUrlAuthenticationEntryPoint
입니다.ExceptionTranslationFilter
와AuthenticationEntryPoint
는 이 게시글을 참고하세요. - 클라이언트 브라우저는 전달받은 URL로 Redirect 됩니다.
- 서버가 로그인 페이지에 필요한 리소스를 전달합니다.
여기까지가 Redirect 되는 절차에 대한 설명입니다.
이번에는 실제로 클라이언트가 인증을 요청했을 경우에 대해 알아봅시다.
인증 정보 검증
ID/PW 가 클라이언트로부터 전달되면, UsernamePasswordAuthenticationFilter
가 이를 검증합니다.
참고로, UsernamePasswordAuthenticaionFilter
는 AbstractAuthenticationProcessingFilter
를 상속받습니다.
아래 그림을 보면서, 자세히 알아보겠습니다.
절차
- 먼저 사용자가 ID와 PW를 전송하면,
UsernamePasswordAuthenticationFilter
라는 필터가 전달받은HttpServletRequest
객체로부터 ID와 PW 값을 가져와,UserPasswordAuthenticationToken
인스턴스를 생성합니다.
이UserPasswordAuthenticationToken
은Authentication
인터페이스의 구현체입니다. -
그리고 생성된
UsernamePasswordAuthenticationToken
은AuthenticationManager
에게 전달받고, 인증 작업을 수행합니다.AuthenticationManager
는 이 포스팅을 참고하세요. - 만약 인증에 실패했다면 아래 절차를 수행합니다.
-
SecurityContextHolder
를 비웁니다. (Thread Local로 관리되던 인증 정보 제거)SecurityContextHolder
는 이 게시글을 참고하세요. RememberMeServices.loginFail
을 실행합니다.
만약 Remember Me 기능을 사용하지 않는다면, 이 절차는 생략합니다.AuthenticationFailureHandler
를 호출합니다.
-
- 만약 인증에 성공했다면 아래 절차를 수행합니다.
SessionAuthenticationStrategy
에게 새로운 로그인 사실을 알립니다.- 인증정보를 담고 있는
Authentication
객체가SecurityContextHolder
에 저장됩니다. RememberMeServices.loginSuccess
를 호출합니다.
역시 Remember Me 기능을 사용하지 않는다면, 이 절차는 생략합니다.-
ApplicationEventPublisher
가InteractiveAuthenticationSuccessEvent
를 publish 합니다.ApplicationEventPublisher
는 Spring 에서 지원하는 이벤트 처리 기능을 수행합니다.
자세한 것은 JavaDoc을 참고하세요. -
마지막으로
AuthenticationSuccessHandler
가 호출됩니다.
보통SimpleUrlAuthenticationSuccessHandler
가 이 역할을 수행하며, 다시 원래 요청으로 Redirect합니다.‘인증되지 않은 사용자’가 ‘인증이 필요한 리소스’를 요청했을 때, 로그인 페이지로 Redirect 되면서 저장된 요청 정보 활용
정리
지금까지 Spring Security가 지원하는 인증 기능 중 하나인, Form 인증의 구조에 대해 알아봤습니다.
이전에 다뤘던 내용들과 더불어 설명이 진행되다보니, 설명에 어려움이 많았습니다.
다음에는 어떻게 Form 인증을 적용하면 되는지, 실제 데모 프로젝트를 통해 알아보겠습니다.