스프링 부트 기반으로 프로젝트를 생성할 때, 가장 무난하게 쓰는 버전이
Java 11 에 SpringBoot 2.7 버전 정도를 많이 쓰는 것으로 알고 있다.
근데 이제 나는 Java 17에 SpringBoot 3.2를 쓰게 되면서 SecurityConfig 설정을 하기 위해 사용되는 방법 중 deprecated된 것들이 있어서 다른 방법으로 작성을 해야 한다는 문제에 직면했다.
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
공홈에서 읽어보면 알겠지만 '컴포넌트 기반 구성(@Bean사용)보안을 위해 변경하였음. 람다식을 사용하여 쓰도록 변경됨. 정도로 바뀌었다고 보면 되겠다.
공통적인 SecurityConfig 설정방법
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// 설정
}
SpringBoot 3.0 미만 SecurityConfig
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors().and()
.httpBasic()
.disable()
.csrf()
.disable()
.formLogin()
.disable()
.logout()
.disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.apply(new JwtSecurityConfig(jwtProvider));
http
.exceptionHandling()
.authenticationEntryPoint(new JwtAuthenticationEntryPoint())
.accessDeniedHandler(new JwtAccessDeniedHandler());
return http.build();
}
간단하게 보자면 SecurityFilterChain의 선언 방식으로 가장 많이 본 모습일 것이다.
그런데 이를 3.0이상에서 이와 같이 선언한다면 'cors()' is deprectaed and marked for removal 이라는 에러처럼
deprecated되었다는 말을 볼 수 있을 것 이다.
이 때 해결 방안은
1. SpringBoot버전을 낮추거나
2. deprecated되지 않은 람다식 방식으로 SecurityConfig를 작성하거나 겠다.
나는 여기서 개정된 방식으로 작업을 진행했다.
SpringBoot 3.0 이상 SecurityConfig
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and()
.cors(httpSecurityCorsConfigurer ->
corsConfigurationSource())
.csrf((csrfConfig) ->
csrfConfig.disable()
)
.headers((headerConfig) ->
headerConfig.frameOptions(frameOptionsConfig ->
frameOptionsConfig.disable()
)
)
.authorizeHttpRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers("/", "/register","/test", "/logout", "/reissue").permitAll()
.requestMatchers("/api/v1/**").permitAll()
.requestMatchers("/chat/**" ).permitAll()
.requestMatchers("/match/**" ).permitAll()
.anyRequest().authenticated()
)
.exceptionHandling((exceptionConfig) ->
exceptionConfig.authenticationEntryPoint(new JwtAuthenticationEntryPoint(new ObjectMapper()))
)
.formLogin((formLogin) ->
formLogin.disable()
)
.logout((logoutConfig) ->
logoutConfig.disable()
)
.sessionManagement((httpSecuritySessionManagementConfigurer ->
httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)))
.addFilterBefore(new JwtAuthenticationFilter(jwtProvider), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//Make the below setting as * to allow connection from any hos
corsConfiguration.setAllowedOrigins(List.of("http://localhost:3000", "프론트 주소"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS","PATCH"));
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setAllowedHeaders(List.of("*"));
corsConfiguration.setExposedHeaders(List.of("*"));
corsConfiguration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
CORS에러 관련된 설정도 해당 config에서 진행해주면 된다.
그래서 원래 WebConfig를 만들어 거기다 선언해뒀는데 해당 Config는 삭제하고 SecurityConfig에서 통합관리한다.