Spring Security Initalization
2개의 WebSecurityConfigurerAdapter 상속클래스가 있다고 가정한다.
-
설정클래스에서 정의한 여러 API 들을 정의
-
API에 맞는 클래스에서 Filter Type Bean을 생성
-
Filter Type Bean 들을 생성하는 클래스는 HttpSecurity ( 각각의 설정클래스의 Filter Type Bean 명단은 SecurityFilterChain의 Filters 필드에 저장 되는 것 기억 )
-
HttpSecurity의 Filter Type Bean(Filters) 들은 WebSecurity 객체에 저장 됨
-
WebSecurity의 FilterChainProxy 객체 생성시 FilterChainProxy의 생성자에 SecurityFilterChain을 전달
-
FilterChainProxy 는 설정클래스의 API에 맞는 Filters 보유 중.
-
DelegatingFilterProxy 는 Servlet Filter로 초기화시 자신의 id 와 같은 "springSecurityFilterChain" id 와 같은 Bean을 찾음.
-
DelegatingFilterProxy는 "springSecurityFilterChain" 의 id 를 가진 Bean에게 요청을 위임하게 됨. 즉 FilterChainProxy에게 요청을 위임
SpringSecurity Filter Structure
인증시도 , 자원접근 의 2가지로 가정
-
인증시도
-
Client의 인증시도 : formLogin()
-
SecurityContextPersistenceFilter 작동
-
SecurityContextPersistenceFilter의 HttpSessionSecurityContextRepository 작동
-
HttpSessionSecurityContextRepository 가 SecurityContext 를 생성하고 Session에 저장. (이후 HttpSessionSecurityContextRepository 는 Session에 저장된 SecurityContext를 저장, 조회하고 참조하는 역할을 함)
-
SecurityContextPersistenceFilter 는 loadContext() 로 Session에 저장된 SecurityContext가 저장되어 있는지 확인 ( 처음 인증시를 가정 중)
-
create SecurityContext 로 새로운 SecurityContext 생성 ( 처음 인증 시나 익명 사용자의 경우 ) 후 SecurityContextHolder 에 저장 후 Chain
-
LogoutFilter는 AntRequestMatcher에 맞지않기 때문에 Chain
-
UsernamePasswordAuthenticationFilter 작동
-
UsernamePasswordAuthentiationFilter는 Authetication 객체를 생성하여 username , password 저장
-
UsernamePasswordAuthenticationFilter 는 Authentication 객체를 매개 값으로 AuthenticationManager(ProviderManager) 를 호출
-
AuthenticationManager(ProviderManager)는 AuthenticationProvider(DaoAuthenticationProvider, RememeberMeAuthenticationProvider, OauthAuthenticationProvider..) 를 호출하여 실질적 인증 검사시작
-
AuthenticaionProvider 구현체는 UserDetailsService등을 이용하여 인증작업 진행
-
AuthenticatiomProvider의 인증 과정을 통과하고 만들어낸 최종 AuthenticaionToken 을 AuthenticationManager > UsernamePasswordAuthenticationFilter 로 반환
-
UsernamePasswordAuthenticationFilter 는 SecurityContextHolder 에 있는 ThreadLocal의 SecurityContext 안에 최종 AuthenticationToken 저장 ( SecurityContextHolder의 SecurityContext는 SecurityContextPersistenceFilter 에서 만들어낸 SecurityContext 객체를 참조한 것)
-
UsernamePasswordAuthenticationFilter 의 후속처리를 위해 SessionManagementFilter 작동
-
세션 동시 제어를 위해 ConcurrentSessionControlAuthenticationStrategy 호출
-
ConcurrentSessionControlAuthenticationStrategy 에서 이전사용자 만료 전략일 경우 이전 Session.exprieNow(), 현재 사용자 접근 차단 전략일 경우 SessionAuthenticationException 발생
-
세선 고정 보호를 위해 ChangeSessionIdAuthenticaionStrategy 호출
-
ChangeSessionIdAuthenticationStrategy 에 의해 새로운 JSESSIONID 생성
-
Session 등록을 위해 RegisterSessionAuthenticationStrategy 호출
-
RegisterSessionAuthenticationStrategy 에 의해 새로운 Session이 등록
-
AuthenticationSucessHandler 동작 후 로그인 완료 페이지로 이동할 때에 SecurityContextPersistenceFilter 가 작동
-
SecurityContextPersistenceFilter가 Session에 최종적인 SecurityContext를 저장, SecurityContextPersistenceFilter의 SecurityContextHolder를 비움(.clear())
- 인증 후 자원 접근 시도
-
DelegatingFilterProxy가 요청을 받아 FilterChainProxy에 위임
-
FilterChainProxy는 가지고 있는 Filter Type Bean 을 이용해 인증, 인가작업 실시
-
SecurityContextPersistenceFilter가 Client 의 Session에 SecurityContext가 있는 지 검사.(Session에 SecurityContext 존재 상태) Session에 SecurityContext가 존재하므로 새로운 SecurityContext는 생성하지 않고 Chain
-
LogoutFilter 는 AntRequestMatcher 에 맞지않으므로 Chain
-
UsernamePasswordAuthenticationFilter의 AntRequestMatcher에 맞지 않으므로 Chain
-
ConcurrentSessionFilter(동시 세션 제어) 가 Client 의 계정으로 인증을 받은 적이 .maximumSessions()이하이므로 Chain
-
RemeberMeAuthenticationFilter 의 작동 조건은 Client Session의 Authentication 객체가 null일 경우임.(Authentication 객체가 null일 경우 Remeber-Me Cookie가 존재시 인증처리시도) Session에 SecurityContext에 Authenticaion이 존재하므로 Chain
-
AnonymousAuthenticationFilter 의 작동 조건은 Client Session의 Authentication 객체가 null일 경우임.(Authentication 객체가 null일 경우 AnonymousAuthenticationToken을 만들고 SecurityContextHolder의 SecurityContext에 저장) SecurityContext에 Authenticaion이 존재하므로 Chain
-
SessionManagermentFilter 의 동작조건은 Client의 Session에 SecurityContext가 없는 경우 이므로 Chain
-
ExceptionTranslationFilter 가 작동
-
ExceptionTranslationFilter 에 Try-Catch 문으로 감싼 chain.doFilter 작동
-
FilterSecurityInterceptor 작동
-
FilterSecurityInterceptor 가 사용자의 SecurityContext에 Authentication객체가 있는지 확인, 없다면 AuthenticationException 발생 (이후 ExceptionTranslationFilter > AutheticaionEntryPoint)
-
Authention 객체가 있을경우 SecurityMatadataSource를 호출하여 경로에 맞는 권한 정보 도출
-
도출된 권한 정보가 없다면 자원 접근
-
도출된 권한 정보가 있다면 AcessDesicionManager 호출
-
AcessDesicionManager 는 Client의 정보를 들을 가지고 AccessDesicionVotor 클래스들을 호출
-
AccessDesicionVotor 의 심사결과를 토대로 AccessDecisionManager는 AcessDeninedException을 발생하거나 접근을 허가
- 이전 계정 만료 전략의 경우 이전 계정의 자원 접근 시도
-
ConcurrentSessionFilter 작동
-
ConcurrentSessionFilter 에서 SessionManagementFilter에서 만료시킨 Session이있나 확인 : isExpired()
-
SessionManagementFilter 가 만료시킨 Session이 있을 경우 오류 메시지를 호출, Logout 처리
'springframework > 시작하자SpringSecurity' 카테고리의 다른 글
26.PasswordEncoder (0) | 2020.09.27 |
---|---|
25.정적 자원 관리 - WebIgnore 설정 (0) | 2020.09.27 |
23.AccessDesicionManager, AccessDecisionVotor (0) | 2020.09.22 |
22.Authorization, FilterSecurityInterceptor (0) | 2020.09.22 |
21.AuthenticationProvider (0) | 2020.09.22 |