[스프링시큐리티] 스프링 시큐리티 동작방식

hyelim·2023년 5월 7일
2

Spring

목록 보기
2/6
post-thumbnail

📌 Spring Security

Spring Security란 인증과, 권한부여, 일반적인 공격에 대한 보호의 기능을 제공하는 프레임워크이다

  • 스프링 시큐리티는 막강한 인증과 인가 기능을 가진 프레임 워크

  • 스프링 기반의 애플리케이션에서 보안을 위한 표준

  • 인터셉터, 필터 기반의 보안 기능을 구현하는 것 보다 스프링 시큐리티를 통해 구현하는 것이 선호됨

Spring Security를 사용하면 어플리케이션의 보안 관련 기능을 자체적으로 구현 할 필요 없이 쉽고 안전하게 구현할 수 있다.

📌 동작방식

Spring Security의 Servlet 보안 지원은 Servlet Filter(이하 Filter)를 기반으로 한다. 클라이언트가 어플리케이션으로 request를 보내면,
Servlet Container는 요청 URI의 경로에 따라 어떤 Filter와 어떤 Servlet을 적용할 것인지 결정한다.

servlet이란? 클라이언트의 Request에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트이다
예를들어, 로그인 시도를 할 때, 서버가 클라이언트에서 입력되는 아이디와 비밀번호를 확인하고 결과를 응답하는데 이러한 역할을 수행하는 것이 서블릿이다

Spring은 여러 Filter중 Servlet Container Lifecycle과 ApplicationContext사이에 연결할 수 있는 DelegatingFilterProxy라는 Filter를 제공한다.

Spring Security의 Servlet Filter 지원은 DelegatingFilterProxy가 감싸고 있는 FilterChainProxy에 의해 수행되며, FilterChainproxy는 Security Filter Chain을 통해 많은 작업을 Security Filter 인스턴스에 위임한다.

위의 설명을 그림으로 나타내면 아래와 같다

Security Filter Chain은 스프링에서 보안과 관련된 여러 Security Filter List를 갖고 있는 객체로 이를 순회하면서 필터링을 실시한다.

SecurityFilterChain에 존재하는 Security Filter순서는 다음과 같다.

  1. ChannelProcessingFilter
  2. ConcurrentSessionFilter
  3. WebAsyncManageIntegrationFilter
  4. SecurityContextPersistenceFilter
  5. HeaderWriterFilter
  6. CorsFilter
  7. CsrfFilter
  8. LogoutFilter
  9. OAuth2AuthorizationRequestRedirectFilter
  10. Saml2WebSsoAuthenticationRequestFilter
  11. X509AuthenticationFilter
  12. AbstractPreAuthenticatedProcessingFilter
  13. CasAuthenticationFilter
  14. OAuth2LoginAuthenticationFilter
  15. Saml2WebSsoAuthenticationFilter
  16. UsernamePasswordAuthenticationFilter
  17. ConcurrentSessionFilter
    … (총 33개의 Spring Security Filter가 존재한다.)

위의 Security Filter중 Security Authentication Filter(UsernamePasswordAuthentication, OAuth2LoginAuthenticationFilter와 같은 인증 필터)는 AuthenticationManager를 통해 인증을 수행한다.

AuthenticationManager는 Spring Security의 필터들이 인증을 수행하는 방법에 대한 명세를 정의해 놓은 인터페이스이다.

이 AuthenticationManager는 일반적으로 ProviderManager로 구현되며, ProviderManager는 여러 AuthenticationProvider에 인증을 위임한다.

여러 AuthenticationProvider중 하나라도 인증에 성공한다면 ProviderManager에게 인증된 Authentication객체를 반환하고 이는 event 기반으로 AuthenticationFilter에 전송된다.

ProviderManager에 설정된 AuthenticationProvider중 어느 것도 성공적으로 인증을 수행할 수 없다면, 인증은 실패할 것이고 알맞는 예외가 ProviderManager에게 건내질 것이다.

인증이 성공할 경우 AuthenticationFilter는 SecuritycontextHolder의 SecurityContext에 인증된 Authentication 객체를 저장할 수 있도록 한다.

📌 Username and Password 인증 방식

아래 그림은 Username and Password 인증 방식의 아키텍처이다

위 그림의 AuthenticationFilter의 역할은 UsernamePasswordAuthenticationFilter가 수행한다.

정리하자면 전체적인 프로세스는 다음과 같다.

  1. 사용자가 로그인 정보와 함께 인증 요청 (HttpRequest)하면, Servlet Filter에 의해서 Security Filter로 Security 작업이 위임되고 여러 Security Filter 중에서 UsernamePasswordAuthenticationFilter(Username and Password Authentication 방식에서 사용하는 AuthenticationFilter)에서 인증을 처리한다.

  2. AuthenticationFilter(UsernamePasswordAuthenticationFilter인데 지금부터 AuthenticationFilter라고 부름)는 Servlet 요청 객체(HttpServletRequest)에서 username과 password를 추출해 UsernameAuthenticationToken(이하 인증 객체)을 생성한다.

  3. AuthenticationFilter는 AuthenticationManager(구현체 : ProviderManager)에게 인증 객체  UsernamePasswordAuthenticationToken 객체를 전달

  4. ProviderManager는 인증을 위해 AuthenticationProvider에게 인증 객체를 전달한다.

  5. AuthenticationProvider는 전달받은 인증 객체의 정보(일반적으로 사용자 아이디)를 실제 DB로 부터 사용자 인증 정보를 가져오는 UserDetailsService에 사용자 정보를 넘겨줌

  6. UserDetailsService는 전달 받은 사용자 정보를 통해 DB에서 알맞는 사용자를 찾고 이를 기반으로 UserDetails객체를 만든다.

  7. 사용자 정보와 일치하는 UserDetails객체를 AuthenticationProvider에 전달한다

  8. AuthenticationProvider은 전달받은 UserDetails를 인증해 성공하면 ProviderManager에게 권한(Authorities)을 담은 검증된 인증 객체를 전달한다.

  9. ProviderManager는 검증된 인증 객체를 AuthenticationFilter에게 전달한다. (event 기반 으로 전달)

  10. AuthenticationFilter는 검증된 인증 객체를 SecurityContextHolder의 SecurityContext에 저장한다.

주의 깊게 살펴봐야할 부분은 UserDetailsService와 UserDetails이다.

실질적인 인증 과정은 사용자가 입력한 데이터 (ID, PW 등) 와 UserDetailsServiceloadUserByUsername()메서드가 반환하는 UserDetails 객체를 비교함으로써 동작한다

따라서 UserDetailsService와 UserDetails구현을 어떻게 하느냐에 따라서 인증의 세부 과정이 달라진다.

*추가 2023.05.20

🏷️ 해당 프로세스에서 작동하는 기본 필터들의 목록 및 순서

아래는 스프링 시큐리티에서 동작하는 기본 필터들의 목록 및 순서이다.

만약 OAuth2 2.0 로그인을 사용한다면 UsernamePasswordAuthenticationFilter 대신에 OAuth2LoginAuthenticationFilter가 호출된다

스프링 시큐리티는 AbstractAuthenticationProcessingFilter를 호출하고, 로그인 방식에 따라 구현체인 UsernamePasswordAuthenticationFilter와 OAuth2LoginAuthenticationFilter가 동작하는 방식이다.

참조

https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html
https://gngsn.tistory.com/160
https://velog.io/@tmdgh0221/Spring-Security-%EC%99%80-OAuth-2.0-%EC%99%80-JWT-%EC%9D%98-%EC%BD%9C%EB%9D%BC%EB%B3%B4#oauth-20

profile
기록용

0개의 댓글