Spring Security Filter Chain
에서 사용자의 요청을 가로챈 후, 어떻게 처리를 진행할까?
사용자가 로그인을 시도한 경우로 인증 처리 흐름을 익혀보자!
Username
과 Password
를 포함한 요청 보내면 Spring Security의 Filter Chain의 Filter 중 UsernamePasswordAuthenticationFilter
가 해당 요청을 받는다.💡
UsernamePasswordAuthenticationFilter
는 사용자가 로그인을 위해 요청을 보내면 가장 먼저 만나는 컴포넌트로, 사용자의 요청 정보(Username
과Password
)를 통한 인증을 처리하는 필터👊
UsernamePasswordAuthenticationFilter
는AbstractAuthenticationProcessingFilter
를 상속받는 하위클래스
AbstractAuthenticationProcessingFilter
는 인증 시도는 하위 클래스에게 맡기고, 인증에 성공하면 인증된 사용자 정보를SecurityCotext
에 저장하는 역할을 한다.
💡 FIiter에서 처리를 시작하는 시작점은
doFilter()
메서드이다.
UsernamePasswordAuthenticationFilter
는 사용자에게 전달 받은 Username
과 Password
를 Spring Security 인증 프로세스에서 이용할 수 있도록 UsernamePasswordAuthenticationToken
을 생성한다.💡
UsernamePasswordAuthenticationToken
은Authentication
인터페이스를 구현한 클래스로Authentication
의 객체를 생성하는 것과 같다고 이해하자
이때, 생성된 Authentication
는 아직 인증을 받지 않은 상태이다.
Authentication
은 UsernamePasswordAuthenticationFilter
를 통해 AuthenticationManager
에게 전달된다. 💡
AuthenticationManager
는 인증 처리를 담당하는 인터페이스로 해당 인터페이스를 구현한ProviderManager
클래스가 실질적인 인증 처리 작업 담당 매니저 일을 한다.
ProviderManager
는 인증 처리를 위해 인증 받지 않은Authentication
를 AuthenticationProvider
에게 전달해 인증을 지시한다.
인증 받지 않은Authentication
를 전달 받은AuthenticationProvider
은 UserDetailsService
를 통해 UserDetails
를 조회한다.
💡잊지말자!
UserDetails
는 데이터베이스 등의 저장소에서 저장된 사용자의 Username, 사용자의 자격을 증명해주는 크리덴셜, 사용자의 권한 정보를 포함하고 있는 컴포넌트!
UserDetailsService
는 데이터베이스와 같은 저장소(해당 그림에서는 크리덴셜 저장소)에서 사용자의 크리덴셜을 포함한 사용자의 정보를 조회한다.
조회한 크리덴셜을 포함한 사용자의 정보를 기반으로 UserDetails
를 생성한 후, 이것을 AuthenticationProvider
에 전달한다. 이 때 검증에 사용된 크리덴셜은 삭제된다.
8.AuthenticationProvider
은 PasswordEncoder
를 이용해 인증 받지 않은Authentication
안에 있는 Password를 암호화한 뒤, UserDetails
에 포함된 크리덴셜과 비교 검증을 한다.
💥이때 비교에 실패하면 Exception을 발생시키고 인증 처리를 중단한다.
Authentication
은 UserDetails
를 이용해 인증된 Authentication
를 생성한다.💡이때 생성된 인증 받은
Authentication
은 비교 검증을 위해 얻은UserDetails
의 정보를 기반으로 생성된다.
인증된Authentication
은 AuthenticationProvider
에 의해 ProviderManager
에 전달 된다.
ProviderManager
는 인증된Authentication
를 UsernamePasswordAuthenticationFilter
에 전달한다.
인증된Authentication
를 전달 받은 UsernamePasswordAuthenticationFilter
는 최종적으로 SecurityContextHolder
를 이용해 SecurityContext
에 인증된Authentication
를 저장한다.
💡 이 때 저장된 인증된
Authentication
, 즉SecurityContext
는 Spring Security의 세션 정책에 따라서 사용되기도 한다.
인증 처리를 위해 생성한UsernamePasswordAuthenticationToken
은 Authentication
인터페이스의 메서드 일부를 구현한 구현 클래스이다.
인증을 위해 생성되는 인증 토큰 또는 인증 성공 후 생성되는 토큰은 UsernamePasswordAuthenticationToken
과 같은 하위 클래스의 형태로 생성되지만 생성된 토큰을 리턴 받거나 SecurityContext에 저장할 경우 Authentication
객체로 리턴되거나 저장된다.
💡우선적으로는 UsernamePasswordAuthenticationToken
이 생성된다는 것을 잊지말자!
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
...
private final Object principal;
private Object credentials;
...
...
UsernamePasswordAuthenticationToken
클래스는 두개의 필드 변수를 가진다.
인증에 필요한 용도의 UsernamePasswordAuthenticationToken
객체를 생성한다.
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
...
public static UsernamePasswordAuthenticationToken unauthenticated(Object principal,
Object credentials) {
return new UsernamePasswordAuthenticationToken(principal, credentials);
}
인증에 성공한 이후 SecurityContext에 저장될 UsernamePasswordAuthenticationToken
객체를 생성한다.
AuthenticationProvider
에 의해 부여된 사용자의 접근 권한 목록.public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
...
public static UsernamePasswordAuthenticationToken authenticated(Object principal,
Object credentials,
Collection<? extends GrantedAuthority> authorities) {
return new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
}
인증된 Authentication
객체를 저장하는 컴포넌트
SecurityContext
를 관리하는 역할