6. Spring Security 악용 보호
p143
CorsPractice.java
package io.securitylecture.springsecuritylecture.config;
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.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
@EnableWebSecurity
public class CorsPractice {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
// CORS 설정 정의
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://localhost:3000"); // http://localhost:3000에서 오는 요청만 허용합니다. (프론트엔드 애플리케이션 URL로 변경 가능)
configuration.addAllowedMethod("*"); // 모든 HTTP 메서드 허용
configuration.addAllowedHeader("*"); // 모든 헤더 허용
// URL에 CORS 설정 적용
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/", "/hello").permitAll() // 인증 없이 접근 허용
.anyRequest().authenticated()
)
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // CORS 설정 적용
//CORS 설정을 적용하여 corsConfigurationSource에서 정의한 CORS 정책을 필터 체인에 포함시킵니다.
.csrf(csrf -> csrf.disable()); // CSRF 보호 비활성화 설정
//REST API와 같이 상태가 없는 요청에서 필요하지 않으므로 간편하게 비활성화합니다.
return http.build();
}
}
cors_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CORS Test</title>
</head>
<body>
<script>
fetch("http://localhost:8080/hello")
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error("CORS Error:", error));
</script>
</body>
</html>
p151
CsrfConfig.java
package io.securitylecture.springsecuritylecture.config;
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.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import static org.springframework.security.config.Customizer.withDefaults;
import java.util.Arrays;
@Configuration
public class CsrfConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated() // 모든 요청은 인증이 필요
)
.formLogin(withDefaults()) // 기본 로그인 설정
.csrf(withDefaults()) // 기본 CSRF 보호 활성화
.cors(cors -> cors.configurationSource(corsConfigurationSource())); // CORS 설정 추가
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:63342")); // 허용할 출처 추가
configuration.setAllowedMethods(Arrays.asList("GET", "POST")); // 허용할 HTTP 메서드
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type", "X-CSRF-TOKEN"));
configuration.setAllowCredentials(true); // 자격 증명(쿠키 등) 허용 설정
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
crsf_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF Test</title>
</head>
<body>
<button onclick="submitForm()">Submit Form</button>
<script>
async function submitForm() {
const csrfResponse = await fetch("http://localhost:8080/csrf-token", { credentials: "include" });
const csrfText = await csrfResponse.text();
const csrfToken = csrfText.split(": ")[1]; // CSRF Token 추출
const submitResponse = await fetch("http://localhost:8080/submit-csrf", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": csrfToken
},
credentials: "include"
});
if (submitResponse.ok) {
alert("Form submitted successfully with CSRF protection!");
} else {
alert("Failed to submit form. CSRF protection prevented the request.");
}
}
</script>
</body>
</html>
Last updated