좀더 깔끔한 링크
www.notion.so/Spring-Security-2-288be82555e24f5d91fbae4c672f53f2
UsernamePasswordAuthenticationFilter와 SecurityContextPersistenceFilter 가
인증한 authentication 객체를 SecurityContextHolder에 넣어줌.
UsernamePasswordAuthenticationFilter
-
폼 인증을 처리하는 필터
-
처리 한 후 상위 클래스인 abstractauthenticationProcessingFilter에서
인증한 authentication 객체를 SecurityContextHolder에 넣어줌.
SecurityContextPersistenceFilter
- 세션에 authentication 객체가 있는지 확인
- authentication 객체가 존재하면 세션에 저장
- 세션에 저장한 객체를 요청이 발생하면 세션에서 가져와서 사용
Spring SecurityFilter
FilterChainProxy
- url 패턴이 체인에 들어있는 패턴과 일치하는 체인의 목록을 가져옴
- 목록들은 SecurityConfig에서 설정하는거에 따라 filter의 갯수가 달라짐
- SecurityConfig는 하나의 filterChain으로 여러개의 SecurityConfig의 사용이 가능하며
- url패턴이 동일할 경우는 각각 order로 순서를 지정해줘야 한다.
- 웬만하면 url패턴을 다르게 하는것이 좋음.
- 보통 SpringSeucirtyFilterChain 라는 이름의 빈으로 등록된다.
DelegatingFilterProxy
- Spring Ioc Container에 들어있는 bean에게 자신이 할일을 위임하는 필터
- 보통 FilterChainProxy에 위임함.
- 위임할때 bean의 이름으로 지정해서 위임함
AccessDecisionManager 인가(Authorize) 시작
-
이미 인증을 거친 사용자가 특정한 리소스에 접근을 할때 허용 할것인가
-
유효한 요청인가 를 결정하는 인터페이스
-
인가(Authorize)를 할때 사용하는 인터페이스
-
AccessDecisionVoter가 목록으로 존재함.
-
목록들을 거치면서 유효한지 확인. 전략에 맞지 않으면 익셉션 발생.
-
구현체로 AffirmativeBased를 사용하면 하나라도 허용하면 허용 ( 기본으로 사용되는 전략 )
-
ConsensusBased 다수결로 결정
-
UnaimousBased 만장일치
-
3개의 구현체가 존재함
-
보통 AffirmativeBased를 사용
AccessDecisionManager 또는 AccessDecisionVoter 를 Custom
- ROLE의 계층을 설정하고 싶다면 SecurityConfig에서 ExpressionHandler을 수정하면 된다.
public SecurityExpressionHandler expressionHandler() {
RoleHierarchyImpl role = new RoleHierarchyImpl();
role.setHierarchy("ROLE_ADMIN > ROLE_USER");
DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
handler.setRoleHierarchy(role);
return handler;
}
FilterSecurityInterceptor
- 인증을 다 거친 후 AccessDecisionManager를 이용하여 Access Control 또는 예외 처리를 하는 필터
- 대부분의 경우 FilterChainProxy에 제일 마지막 필터로 들어있다.
ExceptionTranslationFilter
-
필터 체인에서 발생하는 ACcessDeniedException 과 AuthenticationException을 처리하는 필터
-
AuthenticationException 발생 시
-
AUthenticationEntryPoint 발생 ( 인증 재시도)
-
AbstractSecurityInterceptor 하위 클래스 ( FilterSecurityInterceptor 같은 ) 에서 발생하는 예외만 처리
-
UsernamePasswordAuthenticationFilter에서 발생하는 인증 에러는
UsernamePasswordAuthenticationFilter 내부에서 처리함.
-
-
AccessDeniedException 발생 시
- 익명 사용자 라면 AuthenticationEntryPoint 실행 ( 인증 하도록 로그인 페이지를 보여줌 )
- 익명 사용자가 아니라면 AccessDeniedHandler에게 위임
전체 로직
DeligatingFIlterProxy가 ioc에 등록된 FilterChainProxy의 bean의 이름을 지정하여
위임하면 FilterChainProxy에서 WebSecurity HttpSecurity에서 설정된 Filter 목록들을 가져와서
실행시킴
Filter 들이 인증 관련으로 사용되는 객체는 AuthenticationManager 이며
구현체로는 ProviderManager가 있으며 ProviderManager는 여러 Provider를 사용하여
인증을 처리한다.
여러 Provider 중에서 DaoAuthenticationProvider가 존재하며
이 provider는 UserDetailsService라는 Dao Interface 를 사용해서 데이터에서 읽어온 유저정보로
사용자가 입력한 정보가 일치하는지 확인한다.
인증이 성공되면 SecurityContextHolder에 인증 정보를 집어 넣는다.
그 후 FilterChainProxy에서 가져온 filter 목록에는 항상 마지막에는 FilterSecurityInterceptor이 있는데 이 interceptor에서 AccessDecisionManager를 통해서 인가를 처리 한다.
AccessDecisionManager에서는 SecurityContextHolder에 저장된 인증정보에서 role을 확인하여
사용자가 접근할 리소스에 접근할수있는 role을 가지고 있는지 확인 한다.
확인하는 방법은 3가지가 있으며 그 중 기본전략으로 AffirmativeBased가 사용된다.
이 전략은 AccessDecisionVoter 중 하나라도 허용되면 허용하는 전략.
AffirmativeBased가 사용하는 Voter중 WebExpressionVoter가 존재 하는데
이 Voter는 SecurityExpressionHandler을 이용해서 Expression을 처리 한다.
이 Expression에서 계층형 권한을 커스텀 할수 있다.
'개발 > SpringSecurity' 카테고리의 다른 글
Spring Security - 1 (0) | 2020.07.27 |
---|