[Spring] Spring Security 란?

koline·2024년 5월 24일

Spring

목록 보기
9/15

Spring Security


스프링 시큐리티(Spring Security)는 스프링 프레임워크에서 인증, 인가, 권한 등 보안과 관련된 부분을 담당하는 스프링 하위의 프레임워크다.

일반적으로 개발 시 가장 많이 사용되고 가장 먼저 작업되는 부분이 사용자 관리이다.

기본적인 회원가입, 로그인 및 로그아웃부터 세션/토큰 관리, 권한 관리까지 온라인 플랫폼에 맞춰 다양하게 작업되는 인가 & 보안 기능의 개발은 은근히 까다롭고 복잡한 과정과 긴 개발 기간을 요구한다.

스프링 생태계 내에서 이러한 요구사항을 효과적으로 지원하기 위해 개발된 것이 Spring Security이다.




주요 모듈


SecurityContextHolder

SecurityContextHolder는 보안 주체의 세부 정보를 포함하여 응용프래그램의 현재 보안 컨텍스트에 대한 세부 정보가 저장된다. SecurityContextHolder는 기본적으로 SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 방법과 SecurityContextHolder.MODE_THREADLOCAL 방법을 제공한다.

SecurityContext

Authentication을 보관하는 역할을 하며, SecurityContext를 통해 Authentication 객체를 꺼내올 수 있다.

Authentication

Authentication는 현재 접근하는 주체의 정보와 권한을 담는 인터페이스이다. Authentication 객체는 Security Context에 저장되며, SecurityContextHolder를 통해 SecurityContext에 접근하고, SecurityContext를 통해 Authentication에 접근할 수 있다.

UsernamePasswordAuthenticationToken

UsernamePasswordAuthenticationTokenAuthenticationimplementsAbstractAuthenticationToken의 하위 클래스로, 사용자의 IDPrincipal 역할을 하고, PasswordCredential의 역할을 한다. UsernamePasswordAuthenticationToken의 첫 번째 생성자는 인증 전의 객체를 생성하고, 두번째 생성자는 인증이 완려된 객체를 생성한다.

AuthenticationProvider

AuthenticationProvider에서는 실제 인증에 대한 부분을 처리하는데, 인증 전의 Authentication객체를 받아서 인증이 완료된 객체를 반환하는 역할을 한다. 아래와 같은 AuthenticationProvider 인터페이스를 구현해서 Custom한 AuthenticationProvider을 작성해서 AuthenticationManager에 등록하면 된다.

AuthenticationManager

인증에 대한 부분은 SpringSecurityAuthenticatonManager를 통해서 처리하게 되는데, 실질적으로는 AuthenticationManager에 등록된 AuthenticationProvider에 의해 처리된다. 인증이 성공하면 2번째 생성자를 이용해 인증이 성공한(isAuthenticated=true) 객체를 생성하여 Security Context에 저장한다. 그리고 인증 상태를 유지하기 위해 세션에 보관하며, 인증이 실패한 경우에는 AuthenticationException를 발생시킨다.

AuthenticationManagerimplementsProviderManager는 실제 인증 과정에 대한 로직을 가지고 있는 AuthenticaionProviderList로 가지고 있으며, ProividerManager는 for문을 통해 모든 provider를 조회하면서 authenticate 처리를 한다.

UserDetails

인증에 성공하여 생성된 UserDetails 객체는 Authentication객체를 구현한 UsernamePasswordAuthenticationToken을 생성하기 위해 사용된다. UserDetails 인터페이스를 살펴보면 아래와 같이 정보를 반환하는 메소드를 가지고 있다. UserDetails 인터페이스의 경우 직접 개발한 사용자 클래스에 UserDetailsimplements하여 처리할 수 있다.

UserDetailsService

UserDetailsService 인터페이스는 UserDetails 객체를 반환하는 단 하나의 메소드(loadUserByUsername)를 가지고 있는데, 일반적으로 이를 구현한 클래스의 내부에 사용자 객체의 정보를 DB에서 가져오는 Repository를 주입하여 사용자를 조회한다.

PasswordEncoding

AuthenticationManagerBuilder.userDetailsService().passwordEncoder() 를 통해 패스워드 암호화에 사용될 PasswordEncoder 구현체를 지정할 수 있다.

GrantedAuthority

GrantAuthority는 현재 사용자(principal)가 가지고 있는 권한을 의미한다. ROLE_ADMINROLE_USER와 같이 ROLE_*의 형태로 사용하며, 보통 roles 라고 한다. GrantedAuthority 객체는 UserDetailsService에 의해 불러올 수 있고, 특정 자원에 대한 권한이 있는지를 검사하여 접근 허용 여부를 결정한다.




인증 아키텍처


스프링 프레임워크답게 개발 구조가 잘 설계되어 있기 때문에 스프링 생태계에서 제공하는 라이브러리라면 기존의 코드를 변경하지 않고도 그림과 같이 중간에 삽입하여 사용할 수 있다.

  1. 서버에서 사용자의 요청 받음
  1. Authotication Filter가 요청을 가로채고 Authotication Manger로 요청을 위임
  1. Authotication Manager는 등록된 Authotication Provider를 조회하며 인증을 요구
  1. Authotication Provider가 실제 데이터를 조회하여 UserDetails 결과를 반환 (유효한 사용자 정보가 없다면 403 응답)
  1. 결과는 SecurityContextHolder에 저장이 되어 저장된 유저정보를 Controller에서 사용
profile
개발공부를해보자

0개의 댓글