[LG CNS AM Inspire Camp 1기] SpringSecurity (1) - 스프링 시큐리티 시작하기

정성엽·2025년 2월 8일
1

LG CNS AM Inspire 1기

목록 보기
43/53

INTRO

이번 포스팅에서는 스프링 시큐리티(Spring Security) 의 기본 개념과 적용 방법을 정리해보려 한다.

웹 애플리케이션에서 보안은 필수적인 요소이며, 특히 사용자의 인증(Authentication)과 권한 부여(Authorization)를 효과적으로 처리하는 것이 중요하다!

우리는 이를 위해 스프링 시큐리티를 활용할 수 있다.

지금까지 개발한 게시판 프로젝트에는 사실 아직 로그인 기능이 없기 때문에 여기에 로그인/회원가입 기능을 추가하며 스프링 시큐리티를 살펴보자 👀


1. 스프링 시큐리티란?

우리가 사용하는 스프링 시큐리티는 다음과 같은 기능을 제공하는 보안 프레임워크이다.

💡 인증 (Authentication)

인증이란 사용자가 본인이 맞는지를 확인하는 과정이다.
일반적으로 다음과 같은 방식으로 사용자를 식별한다.

인증 방식

  • Type 1 (지식 기반 인증) - 사용자가 알고 있는 정보 (ex: 비밀번호)
  • Type 2 (소유 기반 인증) - 사용자가 가지고 있는 정보 (ex: OTP, 인증서, 보안카드)
  • Type 3 (특징 기반 인증) - 사용자의 고유한 생물학적 특징 (ex: 지문, 홍채, 정맥 인식)

두 가지 이상의 인증 방식을 조합하여 2-factor 인증 또는 다중 인증(MFA) 을 구현할 수도 있다.

우리가 일반적으로 사용하는 금융앱의 경우 다중 인증을 거쳐야 하는 것을 생각하면 간단하게 이해할 수 있다.

💡 권한 부여 (Authorization)

권한 부여는 인증된 사용자가 특정 기능을 수행할 수 있는지를 결정하는 과정이다.

RBAC(Role-Based Access Control) 방식이 일반적이며, 역할(Role)에 따라 권한을 부여한다.

💡 접근 통제 (Access Control)

스프링 시큐리티에서는 기밀성(Confidentiality), 무결성(Integrity), 가용성(Availability) 을 보장하기 위해 화면, 기능, 데이터 레이어 에서 접근을 제어할 수 있다.

1. Presentation Layer

  • 권한이 있는 사용자에게만 버튼, 링크, 메뉴를 제공
  • 하지만 클라이언트에서 숨긴다고 보안이 보장되진 않음
    (ex. URL을 직접 입력하면 접근 가능할 수도 있음)

2. 기능 (Business Layer)

  • 요청한 사용자의 권한을 확인한 후 기능을 제공
  • UI에서 기능을 감춰도, 백엔드에서 추가적인 권한 체크가 필요

3. 데이터 (Data Layer)

  • 사용자의 데이터 접근 권한을 확인
  • 특정 권한이 있는 사용자만 특정 데이터에 접근할 수 있도록 제어

내용을 정리는 했지만, 간단하게 읽고 넘어가도록 하자..

우리가 스프링 시큐리티를 사용하는 이유는 인증 & 권한 부여 & 접근 통제라는 것만 기억해도 좋을 것 같다!


2. Spring Security 의존성 추가

간단하게 maven에서 스프링 시큐리티를 검색하면 최신 버전을 찾을 수 있다.

Spring Security 의존성 사이트에 접근하여 본인이 사용하는 프로젝트의 의존성에 추가해주면 된다.

Security 의존성을 추가해주면 기본적으로 모든 요청을 인증 후 접근하도록 제한해버린다.

즉, 기본적으로 모든 요청이 인증을 요구하는 상태가 되는 것이다.

따라서, 새로고침을 누르면 다음과 같은 화면을 볼 수 있다.

Result View


Network 탭에서 요청을 살펴보면 response header의 Location이 http://localhost:8080/login 으로 되어있는 모습을 볼 수 있다.

즉, login 페이지로 모든 요청을 리다이렉션 시켜버린다.

우선 이대로 사이트에 접근하고 싶다면 프로젝트의 CLI를 살펴보면 된다.

CLI View

CLI 화면을 살펴보면 security password가 생성된다.

만약, View Template를 사용하고 있다면 Id는 User, 비밀번호는 위에서 생성된 값을 입력하면 우선은 로그인하여 기존 개발 화면을 살펴볼 수 있다!


3. 접근 제어 커스터마이징

우선 기본적인 Security 설정을 추가해보자

일반적으로 대문 페이지, 로그인 페이지, 회원가입 페이지 등은 인증 없이 접근할 수 있어야 한다.

이를 위해 SecurityFilterChain 설정을 추가할 수 있다.

Sample Code

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/", "/login", "/home").permitAll()
                        .requestMatchers("/board/**", "/api/**" ).hasAnyRole("ADMIN", "USER")
                        .anyRequest().authenticated() // 그 외의 모든 요청은 인증을 거쳐야만 사용할 수 있다.
                );
        return http.build();
    }
}

위 코드에서 @EnableWebSecurity 어노테이션과 SecurityFilterChain 인터페이스를 사용하여 @Configuration 빈으로 등록하고 있음을 확인할 수 있다.

그렇다면 이 두 가지는 각각 어떤 역할을 수행할까?

💡 @EnableWebSecurity

@EnableWebSecurity 는 내부적으로 Spring Security의 기본 보안 필터 체인을 자동으로 등록 해주는 어노테이션이다.

우리가 이 어노테이션을 사용하면 다음과 같은 기본 설정이 제공된다.

Spring Security 기본 기능

  • 모든 HTTP 요청이 인증을 요구
  • 기본 로그인 페이지 제공 (/login)
  • 기본 세션 관리 및 보안 필터 적용

여기서 기본 세션 관리 및 보안 필터 적용이라는 부분을 조금 더 살펴보자

Interceptor를 공부하면서 정리한 적이 있었는데, Tomcat 서버 단위(Servlet)에서 처리되는 내용으로 Filter가 존재한다.

Filter 또한 Interceptor, AOP와 마찬가지로 중간에 데이터를 가로채서 전후 작업을 도와주는 역할을 수행한다.

여기서 스프링 시큐리티를 사용하게 되면 내부적으로 다양한 필터(Security Filters)를 사용하여 요청을 감시하게 된다!

따라서, 동작과정을 살펴보면 만약 로그인 요청이 들어올 경우, 이 필터 중에서 UsernamePasswordAuthenticationFilter 가 로그인 요청을 가로채서 인증을 수행한다.

이후, 인증이 완료되면 SecurityContextHolder 에 사용자 정보를 저장하고, 세션을 유지하여 이후 요청에서도 인증된 상태를 유지한다.

우리는 이 SecurityContextHolder에 저장된 데이터를 사용하여 개발을 진행할 수 있다.

💡 SecurityFilterChain

다음으로 설정 파일에서 새롭게 추가된 내용은 SecurityFilterChain 이다.

위에서 Spring Security는 여러 개의 보안 필터(Security Filters)로 구성되며, 인증 및 권한 부여와 같은 보안 작업을 수행한다고 설명했다.

Spring Security는 Servlet Filter 기반으로 동작하며, 모든 HTTP 요청이 SecurityFilterChain을 통해 필터링된다.

따라서, 우리는 SecurityFilterChain을 커스터마이징하여 빈으로 등록하면 우리가 설정한 필터 체인에 맞춰 HTTP 요청이 처리되는 것이다!

Sample Code

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
			.authorizeHttpRequests(auth -> auth
			.requestMatchers("/", "/login", "/home").permitAll()
            .requestMatchers("/board/**", "/api/**" ).hasAnyRole("ADMIN", "USER")
            .anyRequest().authenticated());
        return http.build();
    }

위에서 작성한 코드를 다시 가져와봤다.

우리는 매개변수로 전달받은 HttpSecurity 객체를 사용해서 보안 규칙을 설정할 수 있다.

코드에서 사용된 메서드명으로도 추론할 수 있듯이 request URL을 기반으로 권한을 추가해줄 수 있다!


OUTRO

이번 포스팅에서는 Spring Security의 @EnableWebSecurity 어노테이션과 SecurityFilterChain 인터페이스에 대해 간략히 살펴보았다.

스프링 시큐리티는 필터 체인을 통해 모든 요청을 검사하며, SecurityFilterChain을 빈으로 등록함으로써 이를 커스터마이징할 수 있다.

이를 통해 인증 및 권한 부여 로직을 유연하게 적용할 수 있음을 기억해두자 👊

profile
코린이

0개의 댓글

관련 채용 정보