[Spring] Spring Security 동작원리 (1)

한호성·2022년 11월 16일
0

Spring Security

목록 보기
1/1

글의 목적

프로젝트에 사용된 Spring Security의 동작원리에 대해 공부한 글입니다.
중요하게 사용되는 Class 들의 역할에 대해 설명하고 코드를 확인합니다.

기본 용어 정리 및 중요 Class

  • 인증 (Authentication) : 해당 사용자가 본인이 맞는지 확인하는 절차
  • 인가 (Authorization) : 인증된 사용자가 요청한 자원에 접근 가능한지 결정하는 절차
  • DelegatingFilterProxy : Servlet Filter이며, Spring IoC가 관리하는 FilterChainProxy을 Wrapping 하고 있어서 Servlet Container와 Spring IoC container의 다리 역할을 한다.
  • FilterChainProxy : DelegatingFilterProxy에게 위임받은 요청을 URL에 따라 SeccurityFilterChain에 해당하는 역할을 한다.
  • SecurityContextHolder : 누가 인증했는지에 대한 정보 저장
  • SecurityContext : 현재 인증한 user에 대한 정보를 갖고 있다.
  • Authentication : 현재인증한 user의 정보를 들고 있으며, AuthenticationManger에 의해 제공되는 정보이다.
  • AuthenticationManager - SpringSecurity의 필터에서 인증을 수행하는 방법을 정의하는 api
  • ProviderManager -AuthenticationManger의 구현체이다

동작원리

[그림1]

[그림2]

동작원리

Spring Security를 설정하게 되면 DispathcerServlet에 도달하기전, 서블릿 Filter 구현체에 먼저 도달하게 되어 Filtering 되게 된다.

[그림1] 설명
1 . Client로 부터 요청이 들어온다
2 . 2번과정에서 많은 일들이 일어난다.
2-1) 우선 DelegatingFilterProxy로 요청이 들어오게 되고,
2-2) DelegatingFilterProxy에 들어온 요청을 Spring Container가 관리하는FilterChainProxy에게 위임하게 된다.
2-3) FilterChainProxy는 갖고 있는 SecurityFilterChain들 중 요청에 해당하는 Filter를 거치게 된다. ( 실제로 Custom한 filter들을 FilterChainProxy가 갖고 있다고 생각하면 된다.)
(2번 과정 참고 [그림2])

3.~10 그 후 , AuthenticationManager(구현체 ProviderManager)에 의해 해당하는
AuthenticationProvider의 authenticate() 함수를 통해 인증과정을 거치게 된다.
인증이 진행되면서, SpringSecurityContextHolder에 요청의 인증된 회원정보를 저장하게 된다. 만약 로그인 인증이 되었다면 , 처리 방식에 따라 토큰을 발급하던지 세션DB에 데이터를 저장하면 된다. (그 때 사용되는 객체는 UserDetails, UserDetailsService를 구현한 구현체)가 된다.

Sequence Diagram

Class 코드 분석

DelegatingFilterProxy

위 용어설명에서 말한 것처럼 실제로 Spring IoC 컨테이너가 관리하는 FilterChainProxy에 요청들을 위임하는지에 대해 알아보자

우선 DelegatingFilterProxy를 bean등록하는 SecurityFilterAutoConfiguration 을 들어가게 되면

위의 그림처럼 나오게 되고 bean 등록하는것을 DelegatingFilterProxyRegistrationBean.java class를 통해
AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME; 타고 들어가게 되면 이름이 SpringSecurityFilterChain 나오게 되고 이는 == FilterChainProxy에 속한 SecurityFilterChain 을 만드는데 사용되는 bean이다. 즉, DelegatingFilterProxy가 만들기 위해서는 FilterChainProxy의 SeucrityFilterChain들이 있어야 한다는 것을 의미하고, DelegatingFilterProxy의 delegate에 해당 내용을 세팅하는데 사용된다.

FilterChainProxy

공식문서의 글에 따르면 , FilterChainProxy도 SecurityFilterChain들을 담고 있으며, 단순히 하나의 Chain이 아니라 List<> 형태로갖고 있으며, 각각의 다른 SecurityFilter 들이 담길 수 있다.

요청의 URL 패턴에 따라 SecurityFilterChain 에 해당하는 Filter들을 타도록 된다.

내가 만든영역은 SecurityFilterChain을 커스텀으로 만들고 등록함으로써, Filter들을 탐으로써, 요청들이 해당 역할을 수행하고 나서, 요청들에대한 처리를 한다고 이해하면 되겠다.

내가 구현한 UsernamePasswordAuthenticationFilter.class 를 상속받는 커스텀 Filter

UsernamePasswordAuthenticationFilter.class
(아이디, 패스워드 기반으로 인증을 담당하는 필터이다. AbstractAuthenticationProcessingFilter 을 상속받아서 만들어진 Filter이다.)

Filter에서 사용자의 아이디 및 비번을 통해 UsernamePasswordAuthenticationToken 을 만들어서, AuthenticationManager로 넘겨주고 있다.

(AuthenticationManager는 인터페이스이며, 실제 구현체는 ProviderManager이다.)

AuthenticationManager.authenticate() 함수에서는 어떤 일을 진행할까?

Providers를 순회하면서, supprots() 함수를 통해 해당 Authenticate 클래스를 지원하는지 확인하고, 지원한다면, provider에 구현된, authenticate 함수를 실행한다.
authenticate() 함수에서 인증된 정보를 넘겨주면 publishevent() 함수를 통해 provider에 설정된 handler() 함수로 들어가 그 다음 행동을 진행하게 된다.

중요한 함수 : supports() , authenticate() 이 두 함수를 직접 구현해서 인증절차를 진행할 수 있다.

Reference

https://docs.spring.io/spring-security/reference/servlet/architecture.html
https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-securitycontextholder
https://00hongjun.github.io/spring-security/securitycontextholder/
https://velog.io/@yaho1024/spring-security-delegatingFilterProxy

profile
개발자 지망생입니다.

0개의 댓글