Spring Security를 적용하게 되면 각 필터를 각 순서에 대한 실행된다.
각각의 필터의 목적은 다르며 실행 요청에 따라 처리를 할수도, 스킵이 될 수도 있다.
먼저 필터의 각 역활부터 보기로 한다.
그 다음에 이글의 주요목적인 로그인에대한 필터 인증 과정을 설명하도록 한다.
Spring Security Filter 설명
- SecurityContextPersistenceFilter : SecurityContextRepository에서 SecurityContext를 가져오거나 저장하는 역할을 한다. (SecurityContext는 밑에)
- LogoutFilter : 설정된 로그아웃 URL로 오는 요청을 감시하며, 해당 유저를 로그아웃 처리
- (UsernamePassword)AuthenticationFilter : (아이디와 비밀번호를 사용하는 form 기반 인증) 설정된 로그인 URL로 오는 요청을 감시하며, 유저 인증 처리
- AuthenticationManager를 통한 인증 실행
- 인증 성공 시, 얻은 Authentication 객체를 SecurityContext에 저장 후 AuthenticationSuccessHandler 실행
- 인증 실패 시, AuthenticationFailureHandler 실행
- DefaultLoginPageGeneratingFilter : 인증을 위한 로그인폼 URL을 감시한다.
- BasicAuthenticationFilter : HTTP 기본 인증 헤더(Basic Authorization)를 감시하여 처리한다.
- RequestCacheAwareFilter : 로그인 성공 후, 원래 요청 정보를 재구성하기 위해 사용된다.
- SecurityContextHolderAwareRequestFilter : HttpServletRequestWrapper를 상속한 SecurityContextHolderAwareRequestWapper 클래스로 HttpServletRequest 정보를 감싼다. SecurityContextHolderAwareRequestWrapper 클래스는 필터 체인상의 다음 필터들에게 부가정보를 제공한다.
- AnonymousAuthenticationFilter : 이 필터가 호출되는 시점까지 사용자 정보가 인증되지 않았다면 인증토큰에 사용자가 익명 사용자로 나타난다.
- SessionManagementFilter : 이 필터는 인증된 사용자와 관련된 모든 세션을 추적한다.
- ExceptionTranslationFilter : 이 필터는 보호된 요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달하는 역할을 한다.
- FilterSecurityInterceptor : 이 필터는 AccessDecisionManager 로 권한부여 처리를 위임함으로써 접근 제어 결정을 쉽게해준다.
Spring Security Config DB 인증 설정 (SuccessHandler 및 Login Form 생략)
(authenticationProvider에 대한 역활은 아래에서 확인해 볼 수 있다.)
여기서 확인해야할될 점은 DaoAuthenticationProvider를 설정하는데 암호화 인코딩과 userdetailService를 등록했다는 점이다.
다음은 로그인화면에서 로그인 진행 시(/Login) 인증되는 플로우이다.
(3. UsernamePasswordAuthenticationFilter)
각 필터를 타고 UsernamePasswordAuthenticationFilter에 도달했을때 AbstractAuthenticationProcessingFilter클래스를 통해 로그인 URL인지 확인하고 로그인 요청이 확인 될 시 아이디 패스워드를 가져와서 인증을 위한 객체를 생성한다.
- AuthenticationManager에서 Provider를 통한 인증 실행
- parent인 ProviderManager 로드하여 DaoAuthenticationProvider 호출
DaoAuthenticationProvider 의 추상 클래스인 AbstractUserDetailsAuthenticationProvider 실행
AbstractUserDetailsAuthenticationProvider에서 추상적인 인증과정 형태를 보여주고 있다.
하나의 템플릿 메소드 디자인 패턴이라고 볼 수 있겠다. (AbstractAuthenticationProcessingFilter도 마찬가지)
구체적인 인증과정은 필자가 설정한 DaoAuthenticationProvider로 구현되게 된다.
유저아이디를 통해 유저정보를 로드 할수 있도록 UserDetailService를 정의했었다. (SecurityConfig에서 UserDetailsService를 구현한 클래스를 설정했었다.)
- Provider에서 UserDetailService - loadUserByUsername메소드 호출
여기서 user아이디를 통해서 DB에 접근하여 유저정보를 로드하도록 구현하면 된다.
물론 패스워드를 포함하여 UserDetails 형태의 데이터 객체로 로드되어야 한다.
로드한 UserDetails 데이터로 입력한 패스워드와 비교하여 실패시 Excpeiton을 발생시킨다.
성공시,
- 인증 성공 시 AuthenticationSuccessHandler 실행
--------------------------------------------------------------------------------------
<추가>
http 권한 처리 우선순위
.antMatchers(HttpMethod.POST,"/api/test/test").hasAuthority(ROLE_COMMON)
.antMatchers(""/api/test/**"").hasAuthority(ROLE_PRO)
이렇게 설정하게되면 test/test 에 접근할수 있는 롤은 COMMON이 되고 나머지 test로 시작되는 url 요청은 PRO가 된다.
하지만
.antMatchers(""/api/test/**"").hasAuthority(ROLE_PRO)
.antMatchers(HttpMethod.POST,"/api/test/test").hasAuthority(ROLE_COMMON)
반대로 하게 되면 각 요청이 다 PRO의 권한을 요구하게 된다.
결론 : 먼저 설정한 것이 우선순위를 갖는다는 것을 알 수 있다.
'Security' 카테고리의 다른 글
크롬에서 쿠키 전송 되지 않는다? 외부도메인 SameSite (0) | 2020.03.24 |
---|---|
Spring Security Login에 따른 이전페이지(Referer) URL 이동SavedRequestAwareAuthentication SuccessHandler 소개 (0) | 2019.12.04 |
Spring Security CSRF, Referer 용어 (0) | 2019.05.02 |
Spring Boot 2.0 Security - Static Resource ( favico.ico, css, js , image ) (0) | 2019.04.24 |
댓글