UsernamePasswordAuthenticationFilter
에서 Id + Password를 담은 인증 객체(Authentication)를 생성한다.AuthenticationManager
에게 인증객체를 넘기며 인증 처리를 위임한다.Provider
를 담은 List를 가지고 있고 그 List에서 적절한 Provider
를 찾는다.AuthenticationManager
)는 적절한 Provider(AuthenticationProvider)
에게 인증 처리를 위임한다.Provider
는 input 정보(id, password)를 가지고 실제 인증 처리 역할을 한다.loadUserByUsername(username)
메서드를 호출해서 유저 객체를 요청UserDetailsService
인터페이스에게 loadUserByUsername(username)
요청Repository
에 findById()
메서드로 유저 객체를 조회UsernameNotFoundException
이 발생하고 UsernamePasswordAuthenticationFilter
에서 예외를 처리한다.FailHandler()
에서 후속 처리UserDetails
타입으로 반환된다. (Member
객체도 UserDetails
객체로 변환되어 반환)AuthenticationManager
)는 이제 Password 검증을 시작한다.UserDetails
의 password를 비교BadCredentialException
발생 후 인증 실패UserDetails
와 authorities
를 담은 인증 후 토큰 객체 Authentication
)를 UsernamePasswordAuthenticationFilter
에 전달SecurityContext
에 저장한다.SecurityContextHolder
에서 인증 객체를 사용 가능하게 한다.AutenticationManager
는 인터페이스, ProviderManager
는 구현체AuthenticationProvider
목록 중에서 인증 처리 요건에 맞는 AuthenticationProvider
를 찾아 인증처리를 위임한다.ProviderManager
를 설정하여 AuthenticationProvider
를 계속 탐색 할 수 있다인증 관리자(AuthenticationManager
)는 필터로부터 인증 처리를 지시 받으면 가지고 있는 인증 처리자(AuthenticationProvider
)들 중에서 현재 인증처리를 할 수 있는 Provider
에게 인증 처리를 위임하여 인증 처리 수행 후 인증이 성공한다면 반환받은 인증 객체를 필터로 전달해준다.
만약, 적절한 Provider를 찾지 못한다면, 자신의 부모 객체에 저장된 ProviderManager
도 검색하여 해당 인증을 처리할 수 있는 Provider
가 있으면 인증 처리를 위임하여 반환한다.
AuthenticationProvider
는 인증 처리 시 가장 핵심적인 역할을 한다.
AuthenticationProvider
는 인터페이스이다. 다음 두 개의 메서드를 제공한다.authenticate(authentication)
: 실제적인 인증 처리를 위한 검증 메서드supports(authentication)
: 인증처리가 가능한 Provider 인지 검사하는 메서드authentication
객체를 가지고 로직을 수행한다.UserDetailsService
인터페이스에서 인증을 요구하는 사용자 정보를 조회한다.UserDetails
타입으로 반환UserNotFoundException
발생UserDetails
에 저장된 password와 로그인 시 입력한 패스워드(authentication.password
)가 일치하는지 비교한다.BadCredentialException
발생PasswordEncoder
)를 이용해 두 암호를 비교한다.authenticate(authentication)
에서 검증이 모두 성공하면 최종적으로 인증 객체(Authentication(user, authorities)
)를 생성하여 AuthenticationManager
에 전달한다.당신에게 무엇이 허가 되었는지 증명하는 것
인증된 사용자가 특정 자원에 접근하고자 할 때 접근할 자격이 되는지 증명하는 것을 인가(Authorization)이라 한다.
/user
경로로 자원 접근을 할 때 그 자원에 설정된 권한 (ROLE_USER
)과 사용자가 가진 권한을 서로 심사해서 결정하는 계층user()
라는 메소드에 접근하고자 할 때 해당 메소드에 설정된 권한과 사용자가 가진 권한을 서로 심사해서 결정하는 계층user
)를 핸들링 하고자 할 때 도메인에 설정된 권한과 사용자가 가진 권한을 서로 심사해서 결정하는 계층AuthenticationException
발생AccessDeniedException
발생AccessDecisionManager
에게 맡김FilterSecurityInterceptor
에서 요청을 받아서 인증 여부를 확인한다.AuthenticationException
발생ExceptionTranslationFilter
에서 해당 예외를 받아 다시 로그인 페이지로 이동하는 등의 후처리를 해준다.SecurityMetadataSource
는 자원에 접근하기 위해 설정된 권한 정보를 조회해서 전달해준다.AccessDecisionManager
에게 권한 정보를 전달하여 위임한다.AccessDecisionManager
는 최종 심의 결정자이다.AccessDecisionManager
가 내부적으로 AccessDecisionVoter
(심의자)를 통해 심의 요청을 한다.AccessDeniedException
이 발생ExceptionTranslationFilter
에서 해당 예외를 받아 후처리를 해준다.AffirmativeBased
: OR
연산자와 비슷한 논리ConsensusBased
: 다수결allowIfEqualGrantedDeniedDecisions
를 false로 설정할 경우 접근 거부로 결정된다.UnanimousBased
: AND
연산자와 동일한 논리Authentication
: 인증 정보FilterInvocation
: 요청 정보(antMatcher("/user")
)ConfigAttributes
: 권한 정보(hasRole("USER")
)ACCESS_GRANTED
: 접근 허용(1)ACCESS_DENIED
: 접근 거부(-1)ACCESS_ABSTAIN
: 접근 보류(0)FilterSecurityInterceptor
가 AccessDecisionManager
에 인가 처리 위임AccessDecisionManager
는 자신이 가지고 있는 Voter들에게 정보 (decide(authentication, object, configAttributes)
)를 전달한다.AccessDecisionManager
에선 반환받은 결정 방식을 통해 후처리를 한다.FilterSecurityInterceptor
에 승인 여부 반환AccessDeniedException
예외를 ExceptionTranslationFilter
로 전달