Servlet Request -> Filter(username, password)
Filter -> Manager.authenticate(Authentication)
- Filter에서 username, password로 Authentication 객체를 생성
- UsernamePasswordAuthenticationFilter를 사용하므로 UsernamePasswordAuthenticationToken 객체가 생성됨
- 생성한 Authentication 객체로 Filter가 AuthenticationManager.authenticate() 메소드 호출
- 실제로는 AuthenticationManager를 구현한 ProviderManager를 호출한다
Manager -> Provider.authenticate()
- Manager가 AuthenticationProvider들 중 적절한 Provider로 인증을 위임
- UsernamePasswordAuthenticationFilter를 사용하므로 여기서는 DaoAuthenticationProvider
- 위임받은 Provider의 authenticate 메소드가 호출됨
DaoAuthenticationProvider -> UserDetailsService.loadUserByUsername()
- DaoAuthenticationProvider가 UserDetailsService의 loadUserByUsername 메소드를 호출
- loadUserByUsername 내부에서 DB 조회 등을 거쳐서 UserDetails 객체를 생성
UserDetailsService -> Provider(UserDetails)
- 생성한 UserDetails를 Provider로 반환
- Provider가 반환받은 UserDetails로 인증을 시도
Provider -> SecurityContext(Authentication)
- SecurityContext에 인증 객체 (Authentication) 저장
SecurityContextHolder
SecurityContext
를 획득할 수 있음
SecurityContext context = SecurityContextHolder.getContext();
SecurityContext
- 인증된 유저에 대한 정보를 관리
Authentication
을 획득할 수 있음
Authentication authentication = context.getAuthentication();
Authentication
authentication.getName();
authentication.getPrincipal();
authentication.getAuthorities();
principal
- 유저의 식별정보
- username, password를 사용한 인증인 경우
UserDetails
가 됨
credentials
- 보통 비밀번호를 담고 있음
- 대부분의 경우 인증 완료되면 초기화됨
authorities
- GrantedAuthority(권한) 리스트
- GrantedAuthority
- 유저에게 부여된 권한 정보
- 주로 role 정보임 (ROLE_ADMIN...)
- username, password를 사용한 인증인 경우
UserDetailsService
를 통해 획득할 수 있음
- 시스템 전역에서 사용됨
인증 정보 저장
// ContextHolder로 빈 Context 생성
SecurityContext context = SecurityContextHolder.createEmptyContext()
// 인증 정보 생성
Authentication authentication = new UsernamePasswordAuthenticationToken(...);
// Context에 저장
context.setAuthentication(authentication);
AuthenticationSuccessHandler
- 인증 성공하면 AuthenticationSuccessHandler 실행