-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSecurityConfig.java
More file actions
118 lines (102 loc) · 5.33 KB
/
SecurityConfig.java
File metadata and controls
118 lines (102 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.ftm.server.infrastructure.security;
import com.ftm.server.infrastructure.security.handler.PermissionDeniedHandler;
import com.ftm.server.infrastructure.security.handler.UnauthenticatedAccessHandler;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
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.UrlBasedCorsConfigurationSource;
@Configuration
@EnableWebSecurity(debug = true)
@RequiredArgsConstructor
public class SecurityConfig {
private final UnauthenticatedAccessHandler unauthenticatedAccessHandler;
private final PermissionDeniedHandler permissionDeniedHandler;
// CORS 에서 허용할 HTTP 메서드 목록
public static final List<HttpMethod> CORS_ALLOWED_METHODS =
List.of(
HttpMethod.GET,
HttpMethod.POST,
HttpMethod.PUT,
HttpMethod.PATCH,
HttpMethod.DELETE,
HttpMethod.HEAD);
// CORS 에서 허용할 도메인 목록
public static final List<String> CORS_ALLOWED_ORIGINS =
List.of(
"http://localhost:8080", // 로컬 환경 서버 도메인
"https://dev-api.fittheman.site", // 개발 환경 서버 도메인
"https://fittheman.site"); // 개발 환경 클라이언트 도메인
private static final String[] GET_ANONYMOUS_MATCHERS = {"/api/users/email/duplication"};
private static final String[] POST_ANONYMOUS_MATCHERS = {"/api/users/email/authentication"};
private static final String[] ANONYMOUS_MATCHERS = {"/docs/**"};
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// csrf 비활성화
.csrf(AbstractHttpConfigurer::disable)
// http basic 비활성화
.httpBasic(AbstractHttpConfigurer::disable)
// 폼로그인 비활성화
.formLogin(AbstractHttpConfigurer::disable)
// 로그아웃 비활성화
.logout(AbstractHttpConfigurer::disable)
// 세션 관리
.sessionManagement(
session ->
session.sessionFixation()
.migrateSession() // 세션 고정 보호
.maximumSessions(1) // 동시 로그인 1개 제한
.maxSessionsPreventsLogin(false)) // 기존 세션 만료 후 새 로그인 허용
// 예외 핸들링
.exceptionHandling(
exception ->
exception
// 인증되지 않은 요청 예외 처리
.authenticationEntryPoint(unauthenticatedAccessHandler)
// 접근 권한 부족 예외 처리
.accessDeniedHandler(permissionDeniedHandler))
// cors 설정
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
// 경로 인가 설정
.authorizeHttpRequests(
authorize -> {
authorize
.requestMatchers(ANONYMOUS_MATCHERS)
.permitAll() // 정적 리소스 경로 허용
.requestMatchers(HttpMethod.GET, GET_ANONYMOUS_MATCHERS)
.permitAll()
.requestMatchers(HttpMethod.POST, POST_ANONYMOUS_MATCHERS)
.permitAll();
// TODO: 요청 허용 특정 API 추가 (회원가입, 로그인 등)
// 그 외 모든 요청은 인증 필요
authorize.anyRequest().authenticated();
});
return http.build();
}
// Password 암호화 설정
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// CORS 설정
@Bean
public UrlBasedCorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedHeader("*");
CORS_ALLOWED_ORIGINS.forEach(config::addAllowedOriginPattern);
CORS_ALLOWED_METHODS.forEach(config::addAllowedMethod);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}