[spring] Spring Security Authentication

Nakjoo·2023년 3월 16일
0

[SEB_BE_43]

목록 보기
27/29


✅ spring security 간략한 인증 흐름

  • 사용자가 로그인 request를 Spring Security가 적용된 애플리케이션에 전송한다.
    그러면 그 요청을 많은 필터 들 중에서 UsernamePasswordAuthenticationFilter가 해당 요청을 전달받는다.
  • 요청을 전달받은 UsernamePasswordAuthenticationFilter는 Username과 Password를 이용해 UsernamePasswordAuthenticationToken을 생성해서 Authentication을 생성한다. 방금 생성된 Authentication은 아직 인증이 되지 않은 상태이다.
  • UsernamePasswordAuthenticationFilter가 아직 인증되지 않은 AuthenticationAuthenticationManager에게 전달한다.
    AuthenticationManager는 인증 처리를 총괄하는 역할을 하는 인터페이스고, AuthenticationManager를 구현한 클래스가 ProviderManager이다.
  • ProviderManager로부터 Authentication을 전달 받은 AuthenticationProviderUserDetailsService를 이용해 UserDetails를 조회한다.
  • UserDetailsService는 데이터베이스 등의 저장소에서 사용자의 크리덴셜(Credential)을 포함한 사용자의 정보를 조회한다.
  • UserDetails를 생성한 후, AuthenticationProvider에게 전달한다.
  • AuthenticationProvider는 전달받은 UserDetailsPasswordEncoder를 이용해 암호화된 Password와 인증을 위한 Authentication에 포함된 Password가 일치하는지 검증한다.
    검증에 성공하면 인증된 Authentication을 생성하고, 실패하면 Exception을 발생시키고 인증 처리를 중단한다.
  • AuthenticationProvider는 인증된 AuthenticationProviderManager에게 전달한다.
    지금의 Authentication에는 인증에 성공한 사용자의 정보(Principal, Credential, GrantedAuthorities)를 가지고 있다.
  • ProviderManager는 인증된 Authentication을 다시 UsernamePasswordAuthenticationFilter에게 전달한다.
  • 인증된 Authentication을 전달받은 UsernamePasswordAuthenticationFilter는 마지막으로 SecurityContextHolder를 이용해 SecurityContext에 인증된 Authentication을 저장한다.

이 흐름을 자세히 살펴보자면

✅ UsernamePasswordAuthenticationFilter

UsernamePasswordAuthenticationFilterAbstractAuthenticationProcessingFilter를 상속한다.

UsernamepasswordAuthenticationFilterdoFilter()가 존재하지 않는 이유는 상위 클래스인 AbstractAuthenticationProcessingFilter 클래스가 doFilter() 메서드를 포함하고 있기 때문이다.

결과적으로 로그인 request를 제일 먼저 전달받는 클래스는 AbstractAuthenticationProcessingFilter 클래스이다.

✅ AbstractAuthenticationProcessingFilter

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

✅ UsernamePasswordAuthenticationToken

UsernamePasswordAuthenticationToken은 Spring Security에서 Username/Password로 인증을 수행하기 위해 필요한 토큰이며, 인증 성공 후 인증에 성공한 사용자의 인증 정보가 UsernamePasswordAuthenticationToken에 포함돼 Authentication 객체 형태로 SecurityContext에 저장된다.

✅ Authentication

Authentication은 Spring Security에서의 인증 자체를 표현하는 인터페이스이다.

애플리케이션의 코드상에서 인증을 위해 생성되는 인증 토큰 또는 인증 성공 후 생성되는 토큰은 UsernamePasswordAuthenticationToken과 같은 하위 클래스의 형태로 생성되지만 생성된 토큰을 리턴 받거나 SecurityContext에 저장될 경우에 Authentication 형태로 리턴 받거나 저장된다.

✅ AuthenticationManager

이름 그대로 인증 처리를 총괄하는 매니저 역할을 하는 인터페이스이다.
인증을 위한 Filter는 AuthenticationManager를 통해 느슨한 결합을 유지하고 있으며, 인증을 위한 실질적인 관리는 AuthenticationMangager를 구현하는 구현 클래스를 통해 이루어진다.

✅ ProviderManager

일반적으로 AuthenticationManager 인터페이스의 구현클래스라고 하면 ProviderManager를 가리킨다.

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

✅ AuthenticationProvider

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

Username/Password 기반의 인증 처리는 DaoAuthenticationProvider가 담당하며, DaoAuthenticationProviderUserDetailsService로부터 전달받은 UserDetails를 이용해 인증을 처리한다.

✅ UserDetails

UserDetails는 데이터베이스 등의 저장소에 저장된 사용자의 Username과 사용자의 자격을 증명해주는 크리덴셜(Credential)인 Password 그리고 사용자의 권한 정보를 포함하는 컴포넌트이며, AuthenticationProviderUserDetails를 이용해 자격 증명을 수행한다.

✅ UserDetailsService

UserDetailServiceUserDetails를 로드(load)하는 핵심 인터페이스이다.

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

✅ SecurityContext와 SecurityContextHolder

SecurityContext는 인증된 Authentication 객체를 저장하는 컴포넌트이고, SecurityContextHolderSecurityContext를 관리하는 역할을 담당한다.

SecurityContext가 인증된 Authentication을 포함하고 있고, 이SecurityContext를 다시SecurityContextHolder가 포함하고 있다.

SecurityContextHolderSecurityContext를 포함하고 있는 것은 SecurityContextHolder를 통해 인증된 AuthenticationSecurityContext에 설정할 수 있고 또한 SecurityContextHolder를 통해 인증된 Authentication 객체에 접근할 수 있다는 것을 의미한다.

0개의 댓글