스프링 시큐리티(Spring Security)의 개념과 구조

Kyubo Sim·2025년 4월 11일
0

Spring Security

목록 보기
1/2

스프링 시큐리티란?

스프링 시큐리티는 API가 실행될 때마다 사용자를 인증하는 기능을 제공하는 스프링 기반 보안 프레임워크이다(보안 기능을 모듈화한 개발 도구 모음). 인증(Authentication: 사용자가 누구인지 확인)인가(Authorization: 사용자가 무엇을 할 수 있는지 결정)를 담당한다.즉 스프링 시큐리티는 스프링 애플리케이션의 보안을 위해 사용되며, 요청을 처리하기 전에 요청이 안전한지 판단하고 제어하는 역할을 한다. 스프링 시큐리티를 사용하면 개발자가 일일이 보안 로직을 작성하지 않아도 되도록 도와준다.

  • 💡 프레임워크란? 특정 목적을 달성하기 위해 구조화된 코드의 집합으로, 개발자가 효율적으로 개발할 수 있게 도와주는 틀입니다. 스프링 부트(Spring Boot) 자체가 웹 애플리케이션을 빠르게 만들기 위한 프레임워크이고, 스프링 시큐리티(Spring Security)는 그 안에서 보안을 전담하는 하위 프레임워크이다.

스프링 시큐리티의 특징과 구조

  • 보안을 위한 다양한 설정이 가능하고, 편리한 옵션을 제공
  • 필터(Filter) 기반으로 동작하여, 스프링 MVC와는 독립적으로 작동(필터는 요청/응답 처리의 중간에서 개입할 수 있는 컴포넌트이다)
  • 어노테이션을 통해 권한 설정이 간편하다
  • 기본적으로 세션과 쿠키를 사용하려 인증 정보를 관리한다
  • 세션(Session): 서버에서 로그인 상태를 기억하는 공간
  • 쿠키(Cookie): 클라이언트에 저장된 작은 데이터
  • 인증 관리자(AuthenticationManager: 인증 처리 담당)와 접근 결정 관리자(AccessDecisionManager: 인가 처리 담당)를 통해 리소스 접근을 관리한다

스프링 시큐리티 필터 체인

스프링 시큐리티는 10개 이상의 다양한 필터로 구성된 Security Filter Chain(시큐리티 필터 체인: 보안 처리를 위한 필터들의 연결된 흐름)을 통해 요청을 처리합니다.
필터 체인 작동 방식 간단 예시:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests() // 인가(Authorization)를 설정하는 메서드 체인 시작
                .anyRequest().authenticated() // 모든 요청은 인증 필요
            .and()
            .formLogin(); // 로그인 폼 사용
    }
}

이 코드는 스프링 시큐리티의 보안 설정을 구성하는 코드입니다. 여기서 http.authorizeRequests()는 요청 인가 정책을 설정하기 시작한다는 뜻이고, anyRequest().authenticated()는 모든 요청은 로그인(인증)이 되어 있어야 한다는 뜻입니다. 마지막으로 formLogin()은 스프링 시큐리티에서 제공하는 기본 로그인 화면을 사용하겠다는 설정입니다.
이 설정에 의해 요청이 들어오면 Security Filter Chain이 작동하며, 인증 여부를 확인하고, 인증이 되지 않은 경우 로그인 화면으로 리다이렉트시킵니다.

이 예시에서 실제 사용되는 필터들
1. SecurityContextPersistenceFilter: 요청 시작 시 사용자 인증 정보를 로드하고, 응답 시 저장합니다.
2. UsernamePasswordAuthenticationFilter: 로그인 요청(POST /login)을 감지하고, 사용자 인증 처리합니다.
3. SessionManagementFilter: 세션을 생성하거나 유효성을 검사합니다.
4. ExceptionTranslationFilter: 인증/인가 중 예외 발생 시 로그인 페이지나 에러 페이지로 전환합니다.
5. FilterSecurityInterceptor: 최종적으로 사용자가 요청한 자원에 접근할 수 있는지(인가) 판단합니다.

이 필터들은 내부적으로 체인처럼 연결되어 있으며, 앞 필터가 다음 필터를 호출하는 구조로 동작합니다. 예를 들어 사용자가 인증되지 않은 상태로 보호된 URL에 접근하면 ExceptionTranslationFilter가 이를 감지하고 로그인 페이지로 리다이렉트합니다.

주요 필터

  • SecurityContextPersistenceFilter: 요청/응답 시작과 끝에서 보안 정보를 저장하거나 복원합니다.
  • LogoutFilter: 사용자가 로그아웃할 수 있도록 처리합니다.
  • UsernamePasswordAuthenticationFilter: 사용자의 아이디와 비밀번호로 로그인 요청을 감지하여 인증을 처리합니다.
    1. AuthenticationManager를 통해 인증 수행
    2. 인증 성공 시: 인증 정보를 SecurityContext에 저장-> AuthenticationSuccessHandler 실행
    3. 인증 실패 시: AuthenticationFailureHandler 실행
  • DefaultLoginPageGeneratingFilter: 기본 로그인 화면을 자동 생성합니다.
  • BasicAuthenticationFilter: HTTP 기본 인증을 처리합니다.
  • RequestCacheAwareFilter: 인증 성공 후, 사용자가 요청한 원래 URL로 리다이렉트합니다.
  • SecurityContextHolderAwareRequestFilter: 요청 객체(HttpServletRequest)에 인증 정보를 추가합니다.
  • AnonymousAuthenticationFilter: 인증되지 않은 사용자를 익명 사용자로 처리합니다.
  • SessionManagementFilter: 세션 기반 인증을 관리합니다.
  • ExceptionTranslationFilter: 인증/인가 도중 발생한 예외를 처리하고 응답을 생성합니다.
  • FilterSecurityInterceptor: 인가(Authorization)를 최종적으로 판단하는 필터입니다.

인증 관련 아키텍처 흐름

  1. 사용자가 로그인 폼을 통해 아이디/비밀번호를 입력하고 로그인 요청을 보냅니다.
  2. AuthenticationFilter가 이 요청을 감지하여 처리합니다.
  3. 내부적으로 AuthenticationManager, AuthenticationProvider, UserDetailsService를 호출합니다.
  • UserDetailsService는 인터페이스이며, 이를 개발자가 구현하여 DB에서 사용자 정보를 조회할 수 있습니다. [사용자 ID로 DB에서 사용자 정보를 불러오는 역할]
  1. 인증이 성공하면, 사용자 정보(UserDetails)를 SecurityContextHolder에 저장합니다. [SecurityContextHolder는 세션 정보를 보관하는 저장소 역할을 합니다.]
  2. 서버는 클라이언트에게 세션 ID(JSESSIONID)를 전달하고, 다음 요청부터는 해당 쿠키를 통해 인증 여부를 판단합니다.

Self QnA

스프링 시큐리티는 JPA처럼 스프링 위에서 돌아가는 독자적인 문법이나 어노테이션을 가진건가?
-> YES 스프링 시큐리티는 스프링 프레임워크의 일부로, 보안을 위한 설정과 기능을 제공하고 자체적인 어노테이션, 클래스 등 전용 코드와 패턴이 있다. 대부분 이런 설정은 @Congiguration 어노테이션이 붙은 클래스에서 작성한다. ex) SecurityConfig 클래스
스프링 부트는 설정 기반 자동 구성(auto configuration) 프레임워크이기 때문에, 보안정책도 따로 Java Config으로 정의해서 관리할 수 있게 해주는것이다. 그러므로 이 Config 클래스에서 무엇을 보호할지, 로그인은 어떻게 처리할지, 로그아웃은 어떻게 할지 등을 정리할 수 있다.

formLogin()을 쓰면 로그인 폼이 자동 생성되는가?
-> YES

http
	.formLogin();

설정으로 /login이라는 기본 경로에 기본 로그인 HTML 폼 페이지가 만들어진다.
입력한 ID/비밀번호는 UsernamePasswordAuthenticationFilter에서 자동으로 처리해준다. 즉, 프론트엔드 코드 없이도 동작하는 임시 로그인 화면을 제공해주는 코드이다.

profile
나의 정리 공간

0개의 댓글