본문 바로가기
Develop/Spring

Spring Security 인증 처리 흐름

by jaeyoungb 2022. 11. 21.

Spring Security의 컴포넌트로 보는 인증(Authentication) 처리 흐름 - Username/Password 방식

 

 사용자가 로그인 폼을 이용한 Request(Username, Password 포함)를 Spring Security가 적용된 애플리케이션에 전송

 

 여러 Filter 중에서 UsernamePasswordAuthenticationFilter가 요청을 전달 받음

 

 UsernamePasswordAuthenticationFilter가 Username, Password를 이용해 UsernamePasswordAuthenticationToken을 생성
( UsernamePasswordAuthenticationToken은 Authentication 인터페이스를 구현한 클래스 )

 

 UsernamePasswordAuthenticationFilter는 아직 인증되지 않은 AuthenticationAuthenticationManager에게 전달

( AuthenticationManager는 인증 처리를 총괄하는 매니저 역할을 하는 인터페이스, 이를 구현한 클래스가 ProviderManager )

 

 ProviderManager로부터 Authentication을 전달받은 AuthenticationProviderUserDetailsService를 이용해 UserDetails를 조회

(UserDetails는 데이터베이스에 저장된 사용자의 Username과 사용자의 자격을 증명하는 Password(Credential), 그리고 사용자의 권한 정보를 포함하고 있는 컴포넌트, UserDetailsService가 이 UserDetails를 제공)

 

 UserDetailsService는 데이터베이스에서 사용자의 Credential을 포함한 정보를 조회

 

 조회한 정보를 기반으로, UserDetails를 생성하고 AuthenticationProvider에게 전달

 

 AuthenticationProvider는 PasswordEncoder를 이용해 전달받은 UserDetails에 포함된 암호화된 Password와 인증을 위한 Authentication 안에 포함된 Password가 일치하는지 검증

( 검증에 성공 → UserDetails를 이용해 인증된 Authentication을 생성
  검증에 실패 → Exception 발생시키고 인증 처리 중단 )

 

 AuthenticationProvider는 인증된 Authentication을 ProviderManager에게 전달

( (2)에서의 Authentication은 인증을 위해 필요한 사용자의 로그인 정보를 가짐

  (10)에서의 Authentication은 인증에 성공한 사용자의 정보(Principal, Credential, GrantedAuthorities)를 가짐 )

 

 ProviderManager는 인증된 Authentication을 다시 UsernamePasswordAuthenticationFilter에게 전달

 

 UsernamePasswordAuthenticationFilterSecurityContextHolder를 이용해 SecurityContext에 인증된 Authentication을 저장

( SecurityContext는 Spring Security의 세션 정책에 따라, HttpSession에 저장되어 사용자의 인증 상태를 유지하거나 HttpSession을 생성하지 않고 무상태를 유지)

 

 

Spring Security의 인증 처리 흐름에 대해
- https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html

 

 

 

 

UsernamePasswordAuthenticationFilter

Spring Security가 인증 프로세스에서 이용할 수 있도록 UsernamePasswordAuthenticationToken 생성

AbstractAuthenticationProcessingFilter를 상속

사용자의 로그인 Request를 제일 먼저 만나는 컴포넌트로, 로그인 폼에서 제출되는 Username과 Password를 통한 인증을 처리하는 Filter

 

AbstractAuthenticationProcessingFilter

 UsernamePasswordAuthenticationFilter가 상속하는 상위 클래스로, Spring Security에서 제공하는 Filter 중 하나

HTTP 기반의 인증 요청을 처리하지만, 실질적인 인증 시도는 하위 클래스에 맡기고, 인증에 성공하면 인증된 사용자의 정보를 SecurityContext에 저장하는 역할

 

AbstractAuthenticationProcessingFilter에 대해

- https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-abstractprocessingfilter

 

UsernamePasswordAuthenticationToken

 Spring Security에서 Username과 Password로 인증을 수행하기 위해 필요한 토큰

인증에 성공한 사용자의 정보가 이 토큰에 포함되어 Authentication 객체 형태로 SecurityContext에 저장

 

Authentication

Authentication를 구현하는 클래스에서 가지는 정보들 - Principal, Credentials, Authorities

Principal - 사용자를 식별하는 고유 정보, Username/Password 기반 인증에서는 Username이 Principal이고, 다른 인증 방식에서는 UserDetails가 Principal

Credentials - 사용자 인증에 필요한 Password를 의미, 인증 직후에 ProvideManager가 해당 Credentials를 삭제

Authorities - AuthenticationProvider에 의해 부여된 사용자의 접근 권한 목록
(일반적으로 GrantedAuthority 인터페이스의 구현 클래스는 SimpleGrantedAuthority)

Spring Security에서의 인증 자체를 표현하는 인터페이스로, Authentication 객체 형태로 생성된 토큰을 리턴 받거나 SecurityContext에 저장됨

 

AuthenticationManager

인증을 위한 Filter는 AuthenticationManager를 통해, 느슨한 결합을 유지

인증을 위한 실질적인 관리는 이 인터페이스를 구현하는 클래스를 통해 이루어짐

인증 처리를 총괄하는 매니저 역할을 하는 인터페이스

 

ProviderManager

AuthenticationManager 인터페이스를 구현하는 클래스라고 하면 일반적으로 ProviderManager를 의미

AuthenticationProvider를 관리하고, AuthenticationProvider에게 인증 처리를 위임하는 역할

 

ProviderManager에 대해

- https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-providermanager

 

AuthenticationProvider

AuthenticationManager로부터 인증 처리를 위임 받아 실질적인 인증 수행을 담당하는 컴포넌트

Username/Password 기반의 인증 처리는 DaoAuthenticationProvider가 담당

( DaoAuthenticationProvider는 UserDetailsService로부터 전달받은 UserDetails를 이용해 인증을 처리 )

AuthenticationProvider 인터페이스의 구현 클래스는 AbstractDetailsAuthenticationProvider이고, DaoAuthenticationProvider는 AbstractUserDetailsAuthenticationProvider를 상속한 확장 클래스

 

AuthenticationProvider에 대해

- https://docs.spring.io/spring-security/site/docs/5.7.3/api/org/springframework/security/authentication/AuthenticationProvider.html

 

UserDetails

AuthenticationProvider는 UserDetails를 이용해 자격 증명을 수행

데이터베이스 등의 저장소에 저장된 사용자의 Username과 Password(Credential), 그리고 사용자의 권한 정보를 포함하는 컴포넌트

 

UserDetailsService

UserDetails를 로드(load)하는 핵심 인터페이스

사용자의 정보를 메모리, 데이터베이스 어디에서 로드하든, Spring Security가 이해할 수 있는 UserDetails로 리턴해주기만 하면 됨

 

SecurityContext와 SecurityContextHolder

SecurityContext는 인증된 Authentication 객체를 저장하는 컴포넌트

SecurityContextHolder는 SecurityContext를 관리하는 역할

Spring Security 입장에서, SecurityContextHolder에 의해 SecurityContext에 값이 채워져있으면 인증된 사용자로 간주

 

 

SecurityContext와 SecurityContextHolder의 구조

 

SecurityContext가 인증된 Authentication을 포함, SecurityContext를 다시 SecurityContextHolder가 포함

SecurityContextHolder가 SecurityContext를 포함

SecurityContextHolder를 통해 인증된 Authentication을 SecurityContext에 설정할 수 있음

SecurityContextHolder를 통해 인증된 Authentication 객체에 접근할 수 있음

 

 SecurityContextHolder 기본 전략은 ThreadLocalSecurityContextHolderStrategy

( 현재 실행 쓰레드에 SecurityContext를 연결하기 위해, ThreadLocal을 사용하는 전략 )

( ThreadLocal은 쓰레드 간에 공유되지 않은 쓰레드 고유의 로컬 변수같은 영역을 의미 )

 

SecurityContextHolder에 대해

- https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-securitycontextholder

- https://docs.spring.io/spring-security/site/docs/5.7.3/api/org/springframework/security/core/context/SecurityContextHolder.html

ThreadLocal에 대해

- https://www.baeldung.com/java-threadlocal

- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ThreadLocal.html

'Develop > Spring' 카테고리의 다른 글

Spring Security에서 지원하는 표현식(Spring EL)  (0) 2022.11.22
Spring Security 권한 부여 처리 흐름  (0) 2022.11.22
Spring Security 웹 요청 흐름  (0) 2022.11.19
Spring Security - 기본  (0) 2022.11.19
인증/보안 기초  (1) 2022.11.17