<aside> 💡
<aside> 👉
</aside>
build.gradle 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
SecurityConfig 설정 컴포넌트 생성
<aside> <img src="/icons/question-mark_gray.svg" alt="/icons/question-mark_gray.svg" width="40px" />
사이트간 요청 위조 → 공격자가 사용자의 요청을 위조하여 공격하는 방법
CSRF 성공 조건
Token 인증 방식을 주로 활용하는 REST API 서버에 CSRF 공격을 성공하기는 어렵다. </aside>
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors(withDefaults());
// CSRF 보안 disable
http.csrf(AbstractHttpConfigurer::disable);
// REST API 는 무상태성 이다. -> session : STATELESS
http.sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
// 모든 요청에 대해서 인증정보가 필요하다.
http.authorizeHttpRequests((authorizeRequests) ->
authorizeRequests
.anyRequest().authenticated()
);
return http.build();
}
// CORS 허용
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOriginPattern("*");
configuration.setAllowedHeaders(List.of("Authorization", "Content-Type"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// 모든 API Endpoint 에 동일한 configuration 적용
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
/user/login
(서버 로그인 API)으로 사용자 ID/PW 정보를 요청 본문에 넣어서 요청한다.<aside> <img src="/icons/question-mark_gray.svg" alt="/icons/question-mark_gray.svg" width="40px" />
JwtAuthFilter 를 AuthenticationFilter(UsernamePasswordAuthenticationFilter) 이전에 위치시키는 이유
로그인 요청에 대한 인증 무효화 및 JwtAuthFilter 위치 설정
로그인시, ID/PW 인증을 수행하기 위한 AuthenticationManager 빈 등록
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
// JWT 관련 처리를 수행하는 Util 클래스
private final JwtProvider jwtProvider;
@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors(withDefaults());
http.csrf(AbstractHttpConfigurer::disable);
http.sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
// 로그인 요청에 대해서는 인증 권한이 필요 없음
http.authorizeHttpRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/user/login").permitAll()
.anyRequest().authenticated()
);
// JwtAuthFilter 는 UsernamePasswordAuthenticationFilter 이전에 위치한다.
http.addFilterBefore(new JwtAuthFilter(jwtProvider), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {...}
}