※ 이 글은 정수원님의 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security 강의를 수강하면서 학습한 내용을 정리한 글입니다. 일부 강의 내용을 인용하였으며, 문제가 될 시 인용 부분을 수정 또는 삭제하겠습니다.
AuthenticationManager
인증 처리하는 filter로부터 인증처리를 지시받는 첫번째 클래스.
ID와 Password를 Authentication 인증 객체에 저장하고 이 객체를 AuthenticationManager에게 전달한다. 이 인증에 대해 관리를 하게 된다.
AuthenticationManager 인터페이스를 실제로 구현한 것이 ProviderManager. 이 AuthenticationManager 인터페이스를 구현하면 커스텀 ProviderManager도 만들 수 있다.
AuthenticationProvider 목록 중에서 인증 처리 요건에 맞는 AuthenticationProvider를 찾아 인증 처리를 위임한다. 그래서 실제로 ProviderManager가 ID와 Password를 검증하지는 않는다. 단지 각 인증에 맞는 Provider를 찾아 인증처리를 맡긴다.
만약 ProviderManager에 해당 조건에 맞는 Provider가 없다면, 부모 ProviderManager에서 Provider를 탐색하여 찾는다면 부모 ProviderManager에게 인증을 맡긴다. (예: 위의 사진에서 Oauth 인증일 경우)
인증이 완료되면 자신을 호출한 Filter에게 결과 값을 넘겨준다.
AuthenticationProvider
ID와 Password가 검증하는 실질적인 클래스다. 위의 ProviderManager가 적절한 Provider 선택후 아래와 같은 로직이 동작한다.
AuthenticationProvider는 인터페이스다. 이 인터페이스를 구현하면 커스텀 AuthenticationProvider도 만들 수 있다.
`authenticate` 메서드는 실질적인 인증처리를 하고, `support` 메소드는 인증 처리의 기준을 정한다.
authenticate 동작 순서 살펴보자.
- ID검증: UserDetailsService에서 DB에서 사용자를 조회. 사용자가 없을 경우 UserNotFoundException 예외를 발생시킨다. 성공하면 UserDetails 객체를 반환한다.
- Password 검증: 반환 받은 UserDetails 객체에 저장된 Password와 Authentication에 저장된 Password(로그인시 입력한 Password)를 `matches` 메서드를 이용하여 비교. 일치하지 않는다면 BadCredentialException 예외를 발생시킨다.
- 추가 검증 까지 완료하면 Authentication(유저 정보, 권한 정보)를 AuthenticationManager에게 전달. AuthenticationManager는 Filter에게 전달하고, Filter는 이 정보를 전역적으로 사용할 수 있게 SecurityContext에 전달한다.
References
스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - https://www.inflearn.com/course/%EC%BD%94%EC%96%B4-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/