Backend Engineering

Spring Security를 활용한 인증 흐름 정리

zamezzz 2025. 6. 9. 22:39

오늘은 Spring Security를 활용한 인증 흐름에 대해 간단히 정리하려고 합니다.

 

■ Spring Security란?

먼저 Spring Security에 대해 간략히 개념 정리를 하겠습니다.

 

Spring Security는 Spring 기반 애플리케이션의 보안을 담당하는 프레임워크입니다.

(참고 : https://spring.io/projects/spring-security)


인증(Authentication)과 인가(Authorization)을 중심으로, 세션 관리, CSRF 보호, 패스워드 암호화, OAuth 2.0 연동 등 다양한 보안 기능을 제공합니다.

 

기본적으로 다음 두 가지 역할을 수행합니다.

  • 인증 (Authentication) : 사용자가 누구인지 확인하는 과정. ex) 로그인
  • 인가 (Authorization) : 인증된 사용자가 어떤 자원에 접근할 수 있는지 판단. ex) API 접근 제한

Spring Security는 HTTP 요청이 들어오는 순간부터 필터 체인 기반으로 모든 요청을 감시하고 처리합니다.
따라서 애플리케이션 로직보다 먼저 동작하며, 인증되지 않은 요청은 필터에서 차단됩니다.

 

■ Spring Security 동작 흐름

간단한 흐름과 함께 살펴보면 좀 더 이해하기 편할 것 같습니다.

 

아래 예시와 같은 순서로 동작을 하게 됩니다. 여기서 중요한 점은 요청을 처리하여 해당 Controller로 전달되기 전 까지

모든 인증과 권한 검사는 필터 체인에서 이루어진다는 점입니다.

 

1. 사용자가 로그인 요청

2. UsernamePasswordAuthenticationFilter 에서 로그인 요청 감지

3. AuthenticationManager 에서 인증 시도

4. UserDetailsService 에서 사용자 정보 조회

5. PasswordEncoder 에서 비밀번호 검증

6. SecurityContextHolder 에서 인증 성공 시 사용자 정보 저장

7. 요청 처리을 처리 함. FilterChain 통과 후 해당 Controller로 전달 

 Spring Security 커스터 마이징

Spring Security는 다양한 커스터마이징이 가능합니다. 자주 활용되는 몇 가지 포인트가 있는데, 아래에서 예시 코드와 같이 보겠습니다.

 

  • 로그인 / 로그아웃 경로 변경
http.formLogin().loginPage("/login").permitAll();
http.logout().logoutUrl("/logout").logoutSuccessUrl("/");
  • 인증 실패 시 커스텀 핸들러
http.exceptionHandling() 
	.authenticationEntryPoint(customEntryPoint) // 인증 실패 시 처리 
    .accessDeniedHandler(customAccessDeniedHandler); // 인가 실패 시 처리
  • 세션 관리 옵션
http.sessionManagement() 
	.sessionCreationPolicy(SessionCreationPolicy.STATELESS); // JWT 방식 시 필수
  • 커스텀 필터 추가
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
 

 

스프링 시큐리티는 조금 복잡하고 어렵게 느낄 수 있습니다.

강력한 기능을 쉽게 구현 가능하지만, 그 개념을 모르고 개발을 한다면 추후 이슈 발생 시 해결하는데 어려움이 있을 수 있습니다.

 

다만, 개발 가이드 등을 비롯한 여러 문서가 많으니 충분히 이해하고 잘 활용하면 좋을 것 같습니다.

 

https://docs.spring.io/spring-security/reference/index.html

https://docs.spring.io/spring-security/site/docs/current/api/