FilterChainProxy
에 들어옵니다. FilterChainProxy는 해당 요청을 처리해줄 AuthenticationFilter
의 구현체인 UsernamePasswordAuthenticationFilter
를 선택합니다.username
과 password
를 가지는 UsernamePasswordAuthenticationToken
인증 객체를 생성합니다.AuthenticationManager
에게 전달합니다.AuthenticationManager
는 다수의 AuthenticaitonProvider
에게 전달하여 유효성 검증및 인증을 위임합니다.UserDetailsService
로 이동합니다.loadUserbyUsername()
메서드를 이용하여 데이터베이스에서 해당 데이터를 가지고 와서 UserDetails
로 감쌉니다.(존재하지 않을시 UsernameNotFoundException 발생)AuthenticationProvider
에 UserDetails
를 전달합니다.UserDetails
와 Authentication
(autories()로 호출)을 AuthenticationManager
에 전달합니다.AuthenticationFilter
에 Authentcation
을 전달합니다.SecurityContextHolder
안에 SecurityContext
안에 Authentication
을 저장합니다.클라이언트로 요청이 오면 제일 먼저 FilterChainProxy에 존재하는 필터를 거치게 됩니다. 필터는 Manager나 provider에서 사용할 수 있는 인증 객체를 만드는 역할을 수행합니다.
클라이언트로부터 요청이 오는 데이터를 읽고 사용자의 username
과 password
를 추출하여 UsernamePasswordAuthentication
인증객체를 생성하는 UsernamePasswordAuthenticationFilter
가 대표적으로 존재합니다.
또한 인증을 하지 않은 익명 사용자를 위한 필터도 존재합니다. AnonymousAuthenticationToken
인증객체를 생성하는 AnonymousAuthenticationFilter
필터도 존재합니다.
Authentication
은 사용자의 인증 정보를 저장하는 인증 객체로써, 인증에 사용한 username
과 password
를 담고 인증을 위해 전달되어 사용됩니다.
인증 후 최종 인증 결과가 SecurityContext
에 저장되어 어디서든 참조가 가능합니다.
Authentication 데이터 | 설명 |
---|---|
principal | username 혹은 사용자 객체를 저장합니다. |
credentials | 사용자의 비밀번호를 저장합니다. |
authorities | 사용자에게 부여된 권한 목록을 저장합니다. |
details | 인증 부가 정보 |
authenticated | 인증 여부 |
UsernamePasswordAuthenticationFilter
가 생성하고 AuthenticationManager
가 인증처리를 위해 사용합니다.
AuthenticationManager
은 AuthenticationFilter
로 부터 인증 처리를 명령 받으면 처리가 가능한 AuthenticationProvider
를 골라서 인증 처리 작업을 위임합니다. 또 성공을 한다면 다시 필터에게로 Authentication
인증 객체를 전달 합니다.
AuthenticationManager
는 인터페이스, ProviderManager
는 AuthenticationManager
를 구현한 구현체 입니다.
ProviderManager
는 요건에 맞는 AuthentictaionProvider
를 찾아 인증 처리를 위임하는 클래스입니다.
만약 요건에 맞는 적절한 AuthenticatioinProvider
를 찾지 못한다면 부모 ProviderManager
에서 AuthenticationProvider
를 호출할 수 도 있습니다.
Authentication Provider
는 실제로 인증을 처리합니다. Provider는 2개의 메서드가 존재합니다.
authenticate(Authentication)
: 실제로 인증을 처리하는 메서드입니다.supports(Authentication)
: 해당 Provider가 인증을 처리할 수있는지 여부를 판별합니다.authenticate(Authentication)
메서드에서 실제로 인증을 처리하게 됩니다. 인증을 위한 비교는 3단계로 이루어 집니다. ID 검증
-> PW검증
-> 부가검증
순으로 이루어 지게 됩니다.
아이디 검증
: UserDetailService
의 loadUserByUsername()
메서드를 통해 해당 아이디가 존재하면 userDetail
객체를 반환하고 존재하지 않으면 UserNotFoundException
을 반환합니다.비밀번호 검증
: 반환받은 UserDetail
객체로부터 getPassword()
메서드로 부터 반환 받은 비밀번호와 Authentication
객체의 getPassword()
메서드로부터 반환 받은 비밀번호가 일치한지 확인합니다. 보통 보안상 UserDetail
객체의 비밀번호는 PasswordEncoder
로 비밀번호가 암호화 되어 있습니다.부가검증
: 사용자가 추가적으로 검증과정을 더 거치게 만들 수 있습니다.authenticate(Authentication)
메서드의 검증을 모두 통과하면 Authentication
인증 객체를 AuthenticationManager
객체에게 전달합니다.
SecurityContext
는 Authentication
을 저장하고 필요시 꺼내 쓸 수 있는 클래스입니다. 또한 ThreadLocal
(Thread마다 할당된 고유 공간)에 저장되어 아무곳에서나 참조가 가능하도록 설계되었습니다.
인증이 완료되면 HttpSession에 저장되어 애플리케이션 전역에서 사용 되어질 수 있습니다.
SecurityContextHolder
는 SecurityContext
를 저장하고 반환할 수 있습니다.
SecurityContext 컨텍스트 = SecurityContextHolder.createEmptyContext();
Authentication 인증객체 = new TestingAuthentication("아이디","비밀번호","ROLE_권한");
context.setAuthentication(인증객체);
SecurityContextHolder.setContext(컨텍스트);
SecurityContextHolder
-> SecurityContext
-> Authentication
이 저장됨을 알 수 있습니다.
이해해야 하는 클래스나 객체들이 많고 또 구조가 복잡해서 이해도 쉽게 가지 않습니다. 내일도 복습하여 정확히 어떻게 동작하는지 대략적으로 설명된 부분을 확실히 짚어야 되겠습니다.
없음!