
UsernamePasswordAuthenticationFilter가 해당 요청을 전달받는다.UsernamePasswordAuthenticationFilter는 Username과 Password를 이용해 UsernamePasswordAuthenticationToken을 생성해서 Authentication을 생성한다. 방금 생성된 Authentication은 아직 인증이 되지 않은 상태이다.UsernamePasswordAuthenticationFilter가 아직 인증되지 않은 Authentication을 AuthenticationManager에게 전달한다.AuthenticationManager는 인증 처리를 총괄하는 역할을 하는 인터페이스고, AuthenticationManager를 구현한 클래스가 ProviderManager이다.ProviderManager로부터 Authentication을 전달 받은 AuthenticationProvider는 UserDetailsService를 이용해 UserDetails를 조회한다.UserDetailsService는 데이터베이스 등의 저장소에서 사용자의 크리덴셜(Credential)을 포함한 사용자의 정보를 조회한다.UserDetails를 생성한 후, AuthenticationProvider에게 전달한다.AuthenticationProvider는 전달받은 UserDetails를 PasswordEncoder를 이용해 암호화된 Password와 인증을 위한 Authentication에 포함된 Password가 일치하는지 검증한다.Authentication을 생성하고, 실패하면 Exception을 발생시키고 인증 처리를 중단한다.AuthenticationProvider는 인증된 Authentication을 ProviderManager에게 전달한다.Authentication에는 인증에 성공한 사용자의 정보(Principal, Credential, GrantedAuthorities)를 가지고 있다.ProviderManager는 인증된 Authentication을 다시 UsernamePasswordAuthenticationFilter에게 전달한다.Authentication을 전달받은 UsernamePasswordAuthenticationFilter는 마지막으로 SecurityContextHolder를 이용해 SecurityContext에 인증된 Authentication을 저장한다.이 흐름을 자세히 살펴보자면
UsernamePasswordAuthenticationFilter는 AbstractAuthenticationProcessingFilter를 상속한다.
UsernamepasswordAuthenticationFilter에 doFilter()가 존재하지 않는 이유는 상위 클래스인 AbstractAuthenticationProcessingFilter 클래스가 doFilter() 메서드를 포함하고 있기 때문이다.
결과적으로 로그인 request를 제일 먼저 전달받는 클래스는 AbstractAuthenticationProcessingFilter 클래스이다.
AbstractAuthenticationProcessingFilter는 HTTP 기반의 인증 요청을 처리하지만 실질적인 인증 시도는 하위 클래스에 맡기고, 인증에 성공하면 인증된 사용자의 정보를 SecurityContext에 저장하는 역할을 한다.
UsernamePasswordAuthenticationToken은 Spring Security에서 Username/Password로 인증을 수행하기 위해 필요한 토큰이며, 인증 성공 후 인증에 성공한 사용자의 인증 정보가 UsernamePasswordAuthenticationToken에 포함돼 Authentication 객체 형태로 SecurityContext에 저장된다.
Authentication은 Spring Security에서의 인증 자체를 표현하는 인터페이스이다.
애플리케이션의 코드상에서 인증을 위해 생성되는 인증 토큰 또는 인증 성공 후 생성되는 토큰은 UsernamePasswordAuthenticationToken과 같은 하위 클래스의 형태로 생성되지만 생성된 토큰을 리턴 받거나 SecurityContext에 저장될 경우에 Authentication 형태로 리턴 받거나 저장된다.
이름 그대로 인증 처리를 총괄하는 매니저 역할을 하는 인터페이스이다.
인증을 위한 Filter는 AuthenticationManager를 통해 느슨한 결합을 유지하고 있으며, 인증을 위한 실질적인 관리는 AuthenticationMangager를 구현하는 구현 클래스를 통해 이루어진다.
일반적으로 AuthenticationManager 인터페이스의 구현클래스라고 하면 ProviderManager를 가리킨다.
AuthenticationProvider를 관리하고, AuthenticationProvider에게 인증 처리를 위임하는 역할을 한다.
AuthenticationManager로부터 인증 처리를 위임받아 실질적인 인증 수행을 담당하는 컴포넌트이다.
Username/Password 기반의 인증 처리는 DaoAuthenticationProvider가 담당하며, DaoAuthenticationProvider는 UserDetailsService로부터 전달받은 UserDetails를 이용해 인증을 처리한다.
UserDetails는 데이터베이스 등의 저장소에 저장된 사용자의 Username과 사용자의 자격을 증명해주는 크리덴셜(Credential)인 Password 그리고 사용자의 권한 정보를 포함하는 컴포넌트이며, AuthenticationProvider는 UserDetails를 이용해 자격 증명을 수행한다.
UserDetailService는 UserDetails를 로드(load)하는 핵심 인터페이스이다.
즉, 사용자의 정보를 메모리에서 로드하든 데이터베이스에서 로드하든 Spring Security가 이해할 수 있는 UserDetails로 리턴해주기만 하면 된다.
SecurityContext는 인증된 Authentication 객체를 저장하는 컴포넌트이고, SecurityContextHolder는 SecurityContext를 관리하는 역할을 담당한다.
SecurityContext가 인증된 Authentication을 포함하고 있고, 이SecurityContext를 다시SecurityContextHolder가 포함하고 있다.
SecurityContextHolder가 SecurityContext를 포함하고 있는 것은 SecurityContextHolder를 통해 인증된 Authentication을 SecurityContext에 설정할 수 있고 또한 SecurityContextHolder를 통해 인증된 Authentication 객체에 접근할 수 있다는 것을 의미한다.