Spring boot) security모듈 있을 때와 없을 때 config처리방식(cors, csrf)
개요)
spring boot 모듈 중
security 모듈을 추가하게 되면
config 처리를 다르게 해주어야 한다.
security 모듈이 없을 때 cors 처리와
security 모듈이 있을 때 cors 처리를 살펴보자
config 설정하는 파일은 두개다
1. CustomServletConfig.java
2. RootConfig.java
CustomServletConfig.java 파일은
CORS처리 할 내용이 담긴 파일이다.
CORS는 Cross Origin Resource Sharing이다.
CORS가 일어났다는 의미는
"리소스가 교차 공유가 일어났다" 는 의미이다.
예를 들어보자
내가 로컬로 프론트 서버, 백엔드 서버를 켰다.
프론트 포트번호는 8080
백엔드 포트번호는 8081
브라우저 입장에서는
프론트 서버, 백엔드 서버
두 개의 출처에서 리소스를 공유하고 있다.
신뢰할 수 없다.
그래서 백엔드 서버로 요청 후 응답을 받을 때
CORS 에러를 낸다.
백엔드 서버에 CORS 에러를 내는 이유는
프론트에서 백엔드로 요청하기 때문이다.
[CustomServletConfig.java]
@Configuration
public class CustomServletConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new LocalDateFormatter());
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(300)
.allowedHeaders("Authorization", "Cache-Control", "Content-Type");
}
}
[RootConfig.java]
@Configuration
public class RootConfig {
@Bean
public ModelMapper getMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
.setMatchingStrategy(MatchingStrategies.LOOSE);
return modelMapper;
}
}
여기에서는 CORS와는 관계 없는 설정이다.
ModelMapper에 대한 클래스를
사용할 때 커스텀하여 사용할 수 있다.
설정한 값의 의미는 아래와 같다.
setFieldMatchingEnabled: 키값과 맞춰서 넣어라
setFieldAccessLevel: private로 설정하라
setMatchingStrategy: Property랑 완전히 똑같이 하지 않고 느슨하게 해라
Security 모듈을 import 한 이후 처리는 다음과 같다.
디렉토리 구조는 아래 사진과 같다.
[CustomServletConfig.java]
package org.zerock.mailapi.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.zerock.mailapi.controller.formatter.LocalDateFormatter;
@Configuration
public class CustomServletConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new LocalDateFormatter());
}
// securityConfig에서 추가로 인해 사용안함
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedOrigins("*")
// .allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS")
// .maxAge(300)
// .allowedHeaders("Authorization", "Cache-Control", "Content-Type");
// }
}
Security 모듈 이전에는
CustomServletConfig.java 파일에서
CORS 처리를 했다.
Security 모듈을 추가하면서
Security에서 제공하는 모듈에서 설정해줘야 한다.
[CustomSecurityConfig.java]
package org.zerock.mailapi.config;
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Configuration
@Log4j2
@RequiredArgsConstructor
public class CustomSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
log.info("--------------------- security config ----------------");
http.cors(httpSecurityConfigurer -> {
httpSecurityConfigurer.configurationSource(configurationSource());
});
http.sessionManagement(sessionConfig -> sessionConfig.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.csrf(config -> config.disable()); // csrf 는 get 방식을 제외한 모든 요청에 "CSRF토큰"을 사용. 테스트 중에는 안하는 걸로 변경
return http.build();
}
@Bean
public CorsConfigurationSource configurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}