Spring Security 기본 인증 흐름

hyunn·2024년 10월 29일
0

Spring

목록 보기
1/1

Intro

Spring Security는 Spring application의 사용자 인증, 권한 부여, CSRF 보호 등 다양한 보안 관련 작업을 담당하는 framework이다.

Spring Security는 Dispatcher Servlet보다 더 앞단에서 filter를 기반으로 작동하며, Spring Security 3.2부터는 xml로 설정하지 않고 java config 설정으로 간단하게 구현할 수 있다.

용어 정리

인증 절차와 모듈을 소개하기 전에 용어를 정리하고자 한다

  • 접근주체 Principal: 보호받는 리소스에 접근하는 대상
  • 비밀번호 Credential: 리소스에 접근하는 대상의 비밀번호
  • 인증 Authentication: 해당 사용자의 신원을 입증하는 과정
  • 인가 Authorization: 서비스 특정 부분에 접근할 수 있는지 권한을 확인하는 과정

Filter 기반으로 동작하는 Spring Security

기본적으로 Client 요청이 들어오면 Filter → DispatcherServlet→ Interceptor를 거쳐 Controller에 전달된다.
Spring Security는 Filter를 사용하여 사용자 인증 및 권한 부여 등의 작업을 수행하고, 요청이 Controller에 도달하기 전에 모든 보안 검사를 수행한다.

Spring Security FilterChain


spring security는 많은 종류의 필터를 제공한다.
사용자의 요청이 애플리케이션의 리소스에 접근하기 전에 Chain 형태로 결합된 필터들을 순차적으로 통과하며 보안관련 작업이 수행된다.

아래는 일반적으로 사용자의 아이디와 비밀번호로 로그인을 시도할 때의 인증 절차다.

인증절차의 대략적인 흐름

1. 사용자가 로그인 정보와 함께 인증 요청을 한다(Http Request).

2. AuthenticationFilter가 해당 요청을 가로채고 정보에 따라 UsernamePasswordAuthenticationToken(인증용 객체)을 만든다.

3. AuthenticationManager(interface)를 구현한 ProviderManager에게 Token을 전달한다.

4. ProviderManager는 가지고 있는 AuthenticationProvider(List 형태로 존재) 중에서 적절한 Provider를 선택하여 인증을 위임한다.

5. 직접적으로 DB에 저장된 사용자 정보를 가져오는 UserDetailsService에게 사용자 정보를 전달한다.

6. UserDetailsService는 전달받은 사용자 이름을 통해 DB에서 User 객체를 조회하고 UserDetails 객체를 만든다 → AuthenticationProvider에게 전달된다.

7. AuthenticationProvider는 전달받은 사용자 정보와 UserDetails(실제 User 객체)를 비교한다.

8. 인증이 완료되었다면 Authentication 객체(UsernamePasswordAuthenticationToken으로 구현됨)를 만들어서 이를 AuthenticationProvider에게 전달하며, AuthenticationFilter에게까지 순차적으로 전달된다.

9. AuthenticationFilter는 UsernamePasswordAuthenticationToken을 SecurityContextHolder에게 전달하고, SecurityContext에 저장한다.

인증과정에 사용되는 모듈

  • Authentication
    • 접근 주체의 정보와 권한을 담는 interface이다.
    • SecurityContext에 담겨 저장되며, SecurityContext는 SecurityContextHolder에 담겨 보관된다.
  • UsernamePasswordAuthenticationToken
    • Authentication을 implements한 객체다.
    • 사용자 인증 전, 인증 후 두 번에 걸쳐 생성되며, 생성자도 상황에 맞게 두 개 존재한다.
      • 사용자가 로그인폼을 작성하며 인증 요청을 할 때 해당 로그인 정보를 통해 객체를 생성하고, 인증에 활용함
      • 인증이 완료되면 UserDetails 객체를 바탕으로 UsernamePasswordAuthenticationToken객체를 새로 만든다. 인증이 완료되어 SecurityContext에 저장되는 Authentication 객체가 이렇게 새로 만들어진 UsernamePasswordAuthenticationToken이다.
  • AuthenticationManager
    • 인증 작업의 진입점 역할을 한다.
    • AuthenticationProvider를 통해 실질적인 인증을 수행한다.
    • 이 interface는 하나의 method를 가지고 있는데, Authentication 객체를 받아 인증과정을 처리하고 인증이 완료된 객체를 반환하거나 실패시 예외를 던지는 역할을 한다.
      Authentication authenticate(Authentication authentication) throws AuthenticationException;
  • AuthenticationProvider
    • 첫 인증 요청에 생성된 UsernamePasswordAuthenticationToken과 DB에서 찾아온 정보로 만든 UserDetails 객체를 AuthenticationProvider가 비교하여 인증을 수행함.

      public class CustomAuthenticationManager implements AuthenticationManager {
      
          private ProviderManager providerManager;
      
          public CustomAuthenticationManager(List<AuthenticationProvider> providers) {
              this.providerManager = new ProviderManager(providers);
          }
      
          @Override
          public Authentication authenticate(Authentication authentication) throws AuthenticationException {
           // 실질적인 인증과정은 providerManager가 수행
              return providerManager.authenticate(authentication);
          }
      }
      
  • ProviderManager
    • AuthenticationManager를 implements한 구현체다.
    • 등록되어있는 AuthenticationProviders(List)를 순회하며 인증에 적절한 Provider를 선택하여 인증을 수행한다.
  • UserDetails
    • DB에 저장되었던 User 객체를 기반으로 UserDetailsService가 생성하는 객체이다.
    • 이후 인증과정을 위해 AuthenticationProvider에게 전달된다.
  • UserDetailsService
    • 사용자 이름 또는 ID를 바탕으로 실질적으로 DB에 접근하는 객체이다.
    • DB에서 가져온 정보를 바탕으로 인증에 사용될 UserDetails 객체를 생성하고 AuthenticationProvider에게 전달한다.
  • GrantedAuthority
    • 사용자의 권한을 나타내는 interface이며, “ROLE_USER”, “ROLE_ADMIN” 등의 문자열로 표현된다.
    • Spring Security에서는 일반적으로 두 가지 방식으로 사용된다.
      • SimpleGrantedAuthority: GrantedAuthoriry의 가장 일반적인 구현체로, ROLE_USER, ROLE_ADMIN 등의 문자열을 캡슐화하여 저장한다.
      • UserDetails 권한목록: UserDetails 객체에 사용자 권한을 나타내도록 List 형태로 저장된다.

references

https://hello-judy-world.tistory.com/216
https://dev-coco.tistory.com/174

0개의 댓글