Spring Security 핵심만 알아보자

Seunghee Lee·2024년 3월 14일

캡스톤

목록 보기
4/10
post-thumbnail

웹 플랫폼의 회원가입은 JWT 와 Spring Security 를 적용하여 구현하였다. 지난 게시글에는 JWT 를 알아봤다면, 이번엔 스프링 시큐리티에 대해 설명하고자 한다. 스프링 시큐리티는 내용이 너무 많고 깊기 때문에 추후 공식 문서를 따로 정리하도록 하고, 지금은 로그인/회원가입에 적용한 시큐리티 핵심만 알아보자.

✓ Spring Security 란

스프링 시큐리티는 인증/인가를 지원하고 주요 공격으로부터 어플리케이션을 보호해주는 프레임워크이다.

사실상 스프링 기반 어플리케이션의 표준 보안 프레임워크이다. 스프링 시큐리티를 실행하려면 자바8 이상의 환경이 필요하다. 회원가입, 로그인/로그아웃, 권한 관리를 위한 인증과 인가의 보안 기능을 제공한다.

✓ Spring Security 를 사용하는 이유

가장 큰 이유는 스프링 보안에 필요한 기능을 제공하기 때문이다.

스프링 시큐리티는 개발 구조가 스프링이라는 프레임워크 안에서 활용하기 적합한 구조로 설계되어 있어 보안 기능을 추가할 때 활용하기 좋다.

✓ Spring Security 아키텍처

기존에 아키텍처를 찾아보면 엄청 복잡해서 머리가 아프다 .. 정말 어렵다 ..

그래서 완전 '핵심만' 간추려 도식화하면 아래와 같다.
(※ 이 그림은 본인이 이해하기 쉽게 도식화한 거라 틀릴 수도 있다.)

인증 과정

  1. 사용자(Client) 가 로그인을 시도한다.

  2. AuthenticationFilter 가 사용자의 인증 정보(ex. ID/PW) 를 받아 Authenticaiton객체를 생성한다.

  3. 생성된 Authentication 객체는 AuthenticationManager 에게 전달된다.

    • 이때 AuthenticationProviderUserDeatilsService 를 호출하여 사용자 상세 정보를 불러온다.
  4. AuthenticationProvider 는 loadUserByUsername 메소드를 통해 UserDetailsService 에 사용자명(username) 을 전달하고, UserDetailsService 는 해당 사용자명에 해당하는 UserDetails 객체를 반환한다.

  5. UserDetails 객체는 Provider 에서 인증을 수행한다.

  6. 인증이 성공하면,ProviderManager 에 권한을 담은 토큰을 전달한다.
    (※ ProviderManager : AuthenticationProvider의 실제 구현체)

  7. ProviderManagerAuthenticationFilter 를 거쳐SecurityContextHolder 의 SecurityContext 에 저장된다.

  8. 이후 시스템은 사용자가 인증된 상태임을 인증하고, 사용자의 권한에 따라 접근을 허용한다.


📍 주의할 점은, 최초 Authentication 과 최종 Authentication 의 상태가 다르다는 점이다!

AuthenticationFilterUsernamePasswordAuthenticationFilter 등을 사용해 인증 요청을 가로채서 사용자의 인증 정보를 수집하고, 이를 Authentication 객체로 매핑하여 AuthenticationManager 에게 전달한다. 그러면, AuthenticationManagerAuthenticationProvider 를 통해 실제 인증을 수행한다. 따라서 AuthenticationProvider 는 주로 비밀번호 확인 또는 외부 시스템과의 인증을 처리하는 로직이 구현된다. 여기서 실제 인증된 Authentication 객체를 생성한다.

👉 정리하면, Authentication 은 Filter 와 Provider 에서 생성되는 데 이 둘의 차이는 인증 유무에 따라 나눌 수 있다.

  • 처음 생성되는 시점은 AuthentcationFilter 가 된다. 이때 Authentication인증되지 않는 상태로 생성된다.
  • 최종 AuthenticationAuthenticationProvider 에서 인증이 완료된 후 생성된다.

인가 과정

  1. 사용자가 특정 URL에 접근을 시도한다.
  2. 시스템은 SecurityContext 에 저장된Authentication 객체로부터 사용자의 인증 정보를 조회한다.
  3. 사용자의 권한(GranedAuthority)을 확인하여 해당 URL 에 접근 가능한지 결정한다.

📍 인가 과정에서는 결국 권한이 있느냐가 가장 중요하다.

스프링 시큐리티는 이를 확인하기 위한 여러 매커니즘을 제공하는데, 가장 흔히 사용되는 방법 중 하나는@PreAuthorize, @PostAuthorize, @Secured 등의 어노테이션을 메서드에 적용하는 것이다. 이 어노테이션들을 통해 특정 메서드에 대한 접근을 특정 권한을 가진 사용자로 제한할 수 있다.

// ex) USER 권한으로 제한
@PreAuthorize("hasRole('USER')")
public void create(Contact contact);
  • 위와 같이 hasRole 메소드를 사용하면 해당 메소드는 ROLE_USER 권한이 있는 사용자만 접근할 수 있다는 뜻이다. 여기서 ROLE_USERROLE_ 은 스프링 시큐리티에서 prefix 되어 있기 때문에 권한명은 USER 만 작성한다.

✓ Spring Security 적용

※ SpringBoot 2.6.0 에서 진행

build.gradle

// Spring Security
implementation 'org.springframework.boot:spring-boot-starter-security'

스프링 시큐리티 의존성이 추가 되었다면 기본적인 시큐리티 기능들을 쓸 수 있는 환경이 만들어 졌다. 이제 본격적인 시큐리티 구현은 회원가입/로그인 구현 게시글에서 함께 다루도록 하겠다.



참고자료
Spring Security 공식문서
토리맘의 한글라이즈 프로젝트: Spring Security

profile
자라나라 개발개발 ~..₩

0개의 댓글