-
AuthenticationManager와 AuthenticationSpring/Spring 2020. 8. 9. 03:05
- SecurityContextHolder는 Authentication을 담고 있는 곳이며
- 실제 Authentication을 만들고 인증을 처리하는 인터페이스는 AuthenticationManager이다.
- AuthenticationManager는 authenticate라는 메서드만을 가지며
- 여기서 authentication은 유저가 입력한 username, password 등의 인증정보를 담고 있다.
- 유효한지 확인 후 UserDetailsService가 return 한 객체를 Principal로 담고 있는 Authentication 객체를 return 해준다.
실제 이러한 인증의 구현체로 ProviderManager을 사용하게 된다.
ProviderManager에 Debug을 걸어서 어떠한 과정으로 인증이 되는지 알아보자.
- 우선 whitewin / 123으로 계정을 하나 만들고 Sign in을 누르자.
- 그러면 인증을 위해 ProviderManager로 가게 된다.
- 파라미터로 들어온 authentication에 principal과 credentials 등이 담긴 것을 알 수 있다.
- 인증은 또 다른 AuthenticationProvider에게 위임하여 진행이 된다.
AUthentication 객체
- Principal : UserDetailsService에서 리턴한 그 객체 ( User )
- Credentials
- GrantedAuthorities
- 최종적으로 유효한 인증인지 확인 후 Authentication 객체를 리턴하게 되며
- 이 이후로 콘텍스트 홀더를 통해 꺼내서 사용할 수 있게 된다.
이렇게 AuthenticationManager가 인증을 마친 뒤 Authentication의 행방은 어떻게 될까?
- 어딘가에서 이 인증이 된 Authentication 객체를 Spring Security에 넣어주어야 할 것이다.
- 최종적으로 인된 Authentication이 SecurityContextHolder로 들어갔기 때문에 우리가 사용 가능하기 때문이다.
크게 2가지 Filter가 Authentication 객체를 SecurityContextHolder에 넣어주게 된다.
간단한 계정 id : whitewin , pw : 123을 만든 후 다음의 코드를 디버깅하여 살펴보면서
이 authentication은 언제 SecurityContextHolder로 들어가게 되는지 알아보자.
1. account 생성 ( whitewin / 123 )
account를 생성할 때 SecurityContextPersistenceFilter 클래스가 요청을 처리하는 데 사용이 된다.
- 조금 더 내려보면 SecurityContextHolder가 매 요청마다 만들어진 Context를 가져오려고 하지만
- 처음 요청은 인증된 사용자가 없기 때문에 가져오는 게 없는 것을 알 수 있다.
- 그리고 요청을 다 끝낸다면 Context를 clear 해주는 일을 하고 있다.
2. account 계정을 만들고 Form Login을 한 상황
- 이번에는 UsernamePasswordAuthenticationFIlter에 걸리게 됐고 Form 인증을 처리하게 된다.
- 앞에서 보았던 AuthenticationManager가 authenticate 하는 상황이 이곳에서 벌어진다.
이렇게 인증을 마치고 객체가 반환되면 어디로 갈까?
- 우선 상속을 받았던 부모 FIlter로 간 후
- 인증이 되었다면 SecurityContextHolder에 들어가는 것을 볼 수 있다.
즉 매 요청마다 SecurityContextHolder에 Context를 비워주고 기존에 있다면 SecurityContextHolder 넣어주는 것이
SecurityContextPersistenceFilter이다.
정리:
1. UsernamePasswordAuthenticationFilter
- 폼 인증 처리를 시큐리티 필터
- 인증된 Authentication 객체를 SecurityContextHolder에 넣어 주는 필터
- SecurityContextHolder.getContext(). setAuthentication(authentication)
2. SecurityContextPersisenceFilter
- SecurityContext를 Http session을 통해 캐시 하며 여러 요청에서 Authentication을 공유하는 필터.
물론 Spring Security에서 기본적으로 제공해주는 stateful 한 세션 저장을 쓰지 않을 수도 있는데
- 매 요청마다 인증에 필요한 정보를 헤더나 요청 본문에 넣은 후 매번 인증을 통해
- SpringSecurityContextHolder에 authentication을 넣어주는 Filter를 만들어 stateless 하게 유지할 수도 있다.
참고 : 인프런(백기선) - 스프링 시큐리티
'Spring > Spring' 카테고리의 다른 글
Mono.just()와 Mono.defer()에 대한 이해 (0) 2021.07.30 1주차 스프링 스터디 (0) 2021.04.19 ThreadLocal 과 SpringSecurity (0) 2020.08.09 SpringSecurityContextHolder와 Authentication (0) 2020.07.23 IOC ( Inversion Of Control ) 와 IOC 컨테이너 (0) 2020.02.22