이전 글 Spring Security 아키텍쳐를 이해했다면 스프링 시큐리티의 인증 방식은 쉽게 이해할 수 있다.

스프링 시큐리티 인증 모델의 중심에는 SecurityContextHolder가 있다. 이는 SecurityContext를 가진다. 스프링 시큐리티는 인증할 때 이 정보를 활용한다.
SecurityContext는 Authentication을 가진다. 이는 principal, credentials, authorities 를 가지고 있다. principal은 사용자를 식별한다. credentials은 주로 비밀번호를 가리킨다. 사용자 인증 후 지워진다. authorities는 권한이다.
Authentication는 두 가지 용도로 사용된다.
1. 인증된 사용자의 현재 인증 정보(principal, credentials, authorieis)를 저장. (SecurityContext가 가지고 있다.)
2. 1번의 Authentication을 얻기 위해, Filter가 사용자가 입력한 데이터를 통해 사용자를 확인해보기 위해 사용. 이 시기에는 SecurityContext의 Authentication은 False이다. AuthenticationManager를 통해 실제 Authentication을 얻어서 SecurityContext에 넣어주게 된다. (이때부터 1번 용도)
Authentication.getAuthorities()으로 얻을 수 있다. 이는 GrantedAuthority 객체들의 Collection이다. 이들은 principal이 얻은 실제 권한들이다. 주로 ROLE_ADMINISTRATOR나 ROLE_HR_SUPERVISOR 같은 'roles'이다.
GrantedAuthority는 application-wide 권한이다. 특정 도메인에 관한 권한이 아니다. 따라서 이 권한을 '직원번호 54번'에 대한 권한으로 사용할 수 없다. 그런 권한 수천개가 있다면 메모리가 부족해지거나 사용자 인증하는데 시간이 엄청 걸릴 것이다. 스프링 시큐리티는 흔한 요구사항을 처리할 수 있다.
AuthenticationManager는 스프링 시큐리티의 필터의 인증 작업을 규정하는 API이다. 이 작업을 통해 Authentication이 Filter(= SecurityFilter를 거쳐 DelegatingFilterProxy)를 통해 반환되어 Controller의 SecurityContextHolder에 저장된다.
ProviderManager는 AuthenticationManager 의 구현체로 주로 사용된다. 이는 AuthenticationProvider들에게 인증 작업을 위임한다. Provider들은 성공, 실패하거나 혹은 결정을 못 내려서 다음 Provider에게 맡긴다는 것을 보여야 한다. 모든 Provider가 인증을 못한다면 인증은 실패하고 ProviderNotFoundException이 발생한다. 이는 ProviderManager가 Authentication에 맞는 Prover를 못 찾겠다는 것을 보이는 특별한 AuthenticationException이다.
각각의 AuthenticationProvider들은 특정한 인증 작업을 시도한다. 예를 들어 어떤 Provider는 사용자 이름과 비밀번호를 검사할 수도 있고, 어떤 건 SAML assertion을 인증할 수 있다. 각각의 Provider가 그들만의 인증 작업을 하고 있기 때문에, AuthenticationManager 빈 하나만 노출시키면서 여러 유형의 인증 작업을 할 수 있다.

AuthenticationManager는 여러 ProviderManager 를 자식으로 둘 수 있다. 여러 SecurityFilterChain의 몇몇 인증 작업이 공통적인 시나리오에서 흔히 보인다.
ProviderManager 는 기본적으로 Provider들이 주는 Authentication 객체 내 민감한 credential 정보를 지운다.
AuthenticationProvider는 특정 유형의 인증 작업을 진행한다. 예를 들어 DaoAuthenticationProvider는 사용자 이름/비밀번호에 기반한 인증을 한다. JwtAuthenticationProvider 는 JWT 토큰으로 인증을 한다.
AuthenticationEntryPoint을 구현해서 사용자를 로그인 페이지로 리디렉션해서 WWW-Authenticate 헤더를 가져오거나 다른 작업을 취할 수 있다.
AbstractAuthenticationProcessingFilter는 사용자의 자격 증명을 인증하기 위한 기본 Filter이다. 이게 인증되기 전에 AuthenticationEntryPoint를 사용해서 자격증명을 요청하기도 한다.
스프링 시큐리티의 인증 절차는 다음과 같다.
