
Spring Framework가 7.0으로, Spring Boot가 4.0으로 메이저 업데이트되면서 Spring Security 또한 7.0 버전으로 진화했습니다.
이번 업데이트는 단순한 버전 올림이 아니라, 보안 설정의 모듈화, 최신 표준 준수, 그리고 개발자 경험 개선에 초점을 맞추고 있습니다.
이번 포스팅에서는 실무 개발자 관점에서 Spring Security 7.0의 핵심 변경 사항과 마이그레이션 포인트를 상세히 정리해 보았습니다.
Security 7을 이해하기 위해서는 먼저 기반이 되는 Spring Framework 7.0의 변화를 알아야 합니다.
Jackson 2.x에서 Jackson 3.x로 강제 전환되는데RestTemplate은 더 이상 기능 개발이 이루어지지 않으며, RestClient 또는 WebClient로의 전환이 필수적입니다.가장 피부로 와닿는 변화는 보안 설정을 작성하는 방식입니다. 가독성과 타입 안전성을 위해 람다(Lambda) 스타일이 강제되며, 설정을 분리할 수 있는 기능이 추가되었습니다.
.and()의 종말과 람다 체이닝 강제기존의 .and() 메서드를 통한 체이닝 방식은 완전히 제거되었습니다.
모든 설정은 독립적인 람다 블록 안에서 이루어져야 합니다.
Security 6.x 이전 스타일 사용 불가하게 되다
// 더 이상 작동하지 않음
http.csrf().disable()
.and()
.authorizeRequests()
.anyRequest().authenticated();
Security 7.0 스타일
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults()); // 기본값 사용 시
return http.build();
}
Security 7에서는 거대한 SecurityFilterChain 빈 하나에 모든 설정을 때려 넣는 대신, 기능별로 설정을 쪼개어 빈으로 등록할 수 있는 Customizer<HttpSecurity> 방식을 공식 지원합니다.
@Configuration
public class SecurityConfig {
// 메인 필터 체인에서는 모듈화된 설정들이 자동으로 취합됨
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 별도 설정 없이 http.build()만 해도 등록된 Customizer들이 적용됨
return http.build();
}
// CSRF 설정 분리
@Bean
Customizer<HttpSecurity> csrfCustomizer() {
return http -> http.csrf(csrf -> csrf.disable());
}
// 로그인 설정 분리
@Bean
Customizer<HttpSecurity> formLoginCustomizer() {
return http -> http.formLogin(login -> login.loginPage("/login"));
}
}
이 방식은 팀 단위로 보안 설정을 나누어 관리하거나, 복잡한 설정을 기능별로 파일로 분리할 때 매우 유용합니다.
authorizeHttpRequests 표준화오랫동안 사용되던 authorizeRequests()와 antMatchers()가 완전히 제거되었습니다.
authorizeRequests(), antMatchers()authorizeHttpRequests(), requestMatchers()기존 hasAnyRole은 OR 조건이었습니다.
여러 권한을 모두 가지고 있어야 접근 가능한 AND 조건을 위한 매니저가 추가되었습니다.
AllAuthoritiesAuthorizationManager: 명시된 모든 권한을 가져야 통과..hasAllRoles(...), .hasAllAuthorities(...)AuthorizationManager 인터페이스 변경커스텀 인가 로직을 작성할 때 사용하던 check() 메서드가 제거되고, authorize() 메서드로 통일되었습니다.
authorize()는 단순 boolean 결과뿐만 아니라 인가 결정의 맥락과 이유를 포함하여 리턴하므로 디버깅과 감사에 유리합니다.
이전 버전에서는 2차 인증를 구현하려면 필터 체인을 복잡하게 커스텀해야 했습니다.
Security 7은 1차 인증 성공 → MFA 필요 → 2차 인증 페이지 이동 → 최종 인증으로 이어지는 흐름을 프레임워크 차원에서 지원합니다.
Note: Spring Security는 '흐름'을 제어해 줄 뿐, 실제 SMS 발송이나 OTP 생성 로직은 개발자가 구현해야 합니다.
React, Vue.js 등 SPA 환경에서는 HTML Form을 쓰지 않아 CSRF 토큰 처리가 까다로웠습니다. 이를 위해 SPA 전용 핸들러가 추가되었습니다.
http.csrf(csrf -> csrf.spa());
이 설정을 사용하면, CSRF 토큰을 쿠키나 헤더를 통해 SPA 클라이언트가 쉽게 다룰 수 있도록 자동으로 구성해 줍니다.
Password4j 기반의 암호화가 통합되어 더 강력한 해싱 알고리즘을 지원합니다.
{id}encodedPassword 형태의 저장 방식을 유지하되, 내부 엔진이 업그레이드되었습니다.RestClient 기반의 설계를 강화했습니다.SecurityConfig의 모든 .and()를 제거하고 람다 DSL로 변환했는가?authorizeRequests → authorizeHttpRequests, antMatchers → requestMatchers로 변경했는가?AuthorizationManager 구현체에서 check() 대신 authorize()를 사용하도록 수정했는가?Spring Security 7.0은 초기 설정 문법이 바뀌어 낯설 수 있지만, 결과적으로 더 안전하고, 읽기 쉽고, 유지보수하기 좋은 코드를 작성하도록 유도합니다.
특히 MFA 워크플로우와 설정 모듈화는 복잡한 엔터프라이즈 애플리케이션 보안을 구축하는 데 큰 도움이 될 것입니다.
새로운 프로젝트를 시작한다면 주저 없이 Spring Boot 4 & Security 7 조합을 선택하시고, 기존 프로젝트는 위 체크리스트를 바탕으로 점진적인 전환을 준비하시기 바랍니다.