본문 바로가기
Archive/Java 풀스택 아카데미

[TIL] 17. 11월 Spring Security

by Lseing 2025. 11. 11.

Spring Security란?

Spring Security는 Spring 기반 애플리케이션의 보안을 담당하는 프레임워크이다. 인증(Authentication)과 인가(Authorization)를 처리하여 애플리케이션을 보호한다.

웹 애플리케이션에서 보안은 필수적이다. Spring Security는 선언적 보안 설정을 통해 복잡한 보안 로직을 간단하게 구현할 수 있도록 도와준다.

1. Spring Security 보안 레이어 이해하기

Spring Security는 필터 체인(Filter Chain) 방식으로 동작한다. 클라이언트의 요청이 실제 애플리케이션에 도달하기 전에 여러 보안 필터를 거치게 된다.

  • 인증(Authentication): "이 사용자가 누구인가?" - 신원을 확인한다.
  • 인가(Authorization): "이 사용자가 무엇을 할 수 있는가?" - 권한을 확인한다.
  • 거부(Reject): 인증/인가 실패 시 401(인증 실패) 또는 403(권한 없음) 오류를 반환한다.

2. 인증(Authentication) vs 인가(Authorization)

보안에서 가장 많이 혼동되는 두 개념인 인증과 인가의 차이를 명확히 이해해야 한다.

- 인증(Authentication) - "누구인가?"

사용자의 신원을 확인하는 과정이다. 사용자가 주장하는 신원이 정말 맞는지 검증한다.

  • 로그인: 아이디와 비밀번호를 입력하여 본인임을 증명
  • JWT 토큰: 발급받은 토큰으로 신원 증명
  • OAuth2/SAML: 제3자 인증 시스템 활용

- 인가(Authorization) - "무엇을 할 수 있는가?"

인증된 사용자가 어떤 리소스나 기능에 접근할 권한이 있는지 확인하는 과정이다.

  • 역할 기반: ROLE_ADMIN만 관리자 페이지 접근 가능
  • 리소스 기반: 본인이 작성한 게시글만 수정 가능
  • URL 패턴: 특정 URL 패턴에 대한 접근 제어

핵심: 인증 없이 인가는 불가능하다. 먼저 "누구인지" 확인한 후에 "무엇을 할 수 있는지" 판단한다.

3. Security Filter Chain 동작 원리

Spring Security의 핵심은 Filter Chain이다. HTTP 요청이 들어오면 여러 보안 필터를 순차적으로 거치면서 검증된다.

주요 필터 순서:

  1. SecurityContextPersistenceFilter
    SecurityContext를 로드하고 저장한다. 세션에서 인증 정보를 가져온다.
  2. UsernamePasswordAuthenticationFilter
    폼 로그인 요청을 처리한다. /login POST 요청을 가로채서 인증을 수행한다.
  3. BasicAuthenticationFilter
    HTTP Basic 인증(Authorization 헤더)을 처리한다.
  4. AuthorizationFilter
    사용자의 권한을 확인하고 접근 가능 여부를 판단한다.
  5. ExceptionTranslationFilter
    인증/인가 과정에서 발생한 예외를 처리한다.

필터 체인을 통과하면 애플리케이션의 Controller에 도달하고, 중간에 실패하면 401(인증 실패)

또는 403(권한 없음) 응답을 반환한다.

4. UserDetailsService - 사용자 인증의 핵심

UserDetailsService는 Spring Security에서 사용자 정보를 로드하는 핵심 인터페이스이다. 로그인 시 입력한 사용자명으로 사용자 정보를 조회하는 역할을 한다.

동작 흐름:

  1. 사용자가 로그인 폼에 아이디와 비밀번호를 입력한다.
  2. Spring Security가 UserDetailsService.loadUserByUsername() 메서드를 호출한다.
  3. 커스텀 구현체에서 데이터베이스를 조회하여 사용자 정보를 가져온다.
  4. UserDetails 객체를 반환하면 Spring Security가 비밀번호를 검증한다.
  5. 사용자를 찾을 수 없으면 UsernameNotFoundException을 발생시킨다.

예제 구현:

5. Spring Security 설정하기

Spring Security의 설정은 SecurityFilterChain 빈을 통해 이루어진다.

더 이상 WebSecurityConfigurerAdapter를 상속받지 않고, 메서드로 설정한다.

주요 설정 항목:

  • authorizeHttpRequests()
    URL 패턴별 접근 권한을 설정한다.
    • .permitAll(): 모든 사용자 접근 허용
    • .authenticated(): 인증된 사용자만 접근
    • .hasRole("ADMIN"): 특정 역할을 가진 사용자만 접근
  • formLogin()
    폼 기반 로그인 설정. 로그인 페이지, 성공/실패 핸들러 등을 구성한다.
  • logout()
    로그아웃 설정. 로그아웃 URL과 성공 후 리다이렉트 경로를 지정한다.
  • csrf()
    CSRF(Cross-Site Request Forgery) 공격 방어 설정. REST API의 경우 비활성화할 수 있다.

핵심 원칙: 보안 설정은 구체적인 것부터 일반적인 순서로 작성해야 한다. /admin/**를 /**보다 먼저 설정해야 한다.