diff --git a/src/main/java/com/smunity/server/global/security/config/InMemoryUserDetailsManagerConfig.java b/src/main/java/com/smunity/server/global/security/config/InMemoryUserDetailsManagerConfig.java new file mode 100644 index 0000000..ec05a2e --- /dev/null +++ b/src/main/java/com/smunity/server/global/security/config/InMemoryUserDetailsManagerConfig.java @@ -0,0 +1,29 @@ +package com.smunity.server.global.security.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; + +@Configuration +@RequiredArgsConstructor +public class InMemoryUserDetailsManagerConfig { + + private final SwaggerProperties swaggerProperties; + private final PasswordEncoder passwordEncoder; + + @Bean + public InMemoryUserDetailsManager inMemoryUserDetailsManager() { + return new InMemoryUserDetailsManager(createUserDetails()); + } + + private UserDetails createUserDetails() { + return User.builder() + .username(swaggerProperties.getUsername()) + .password(passwordEncoder.encode(swaggerProperties.getPassword())) + .build(); + } +} diff --git a/src/main/java/com/smunity/server/global/security/config/SecurityConfig.java b/src/main/java/com/smunity/server/global/security/config/SecurityConfig.java index 55d4b04..21fc43e 100644 --- a/src/main/java/com/smunity/server/global/security/config/SecurityConfig.java +++ b/src/main/java/com/smunity/server/global/security/config/SecurityConfig.java @@ -14,6 +14,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -38,13 +39,39 @@ public PasswordEncoder passwordEncoder() { } /** - * Spring Security의 필터 체인 설정 구성 + * Spring Security 의 formLogin 필터 체인 설정 구성 */ @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception { + // Swagger UI 및 API 문서 경로, 로그인 페이지에 대한 보안 설정 + http.securityMatcher("/swagger-ui/**", "/v3/api-docs/**", "/login"); + + // 로그인 성공 시 Swagger UI 로 이동 + http.formLogin(authorize -> authorize + .defaultSuccessUrl("/swagger-ui/index.html") + .permitAll() + ); + + // 경로별 인가 작업 + http.authorizeHttpRequests(authorize -> authorize + .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").authenticated() + .anyRequest().permitAll() + ); + + return http.build(); + } + + /** + * Spring Security 의 JWT 필터 체인 설정 구성 + */ + @Bean + public SecurityFilterChain jwtFilterChain(HttpSecurity http) throws Exception { // CSRF 보호 비활성화 http.csrf(AbstractHttpConfigurer::disable); + // 세션 사용 안함 + http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + // HTTP 응답 헤더 설정 http.headers(headersConfigurer -> headersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)); @@ -62,8 +89,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 경로별 인가 작업 http.authorizeHttpRequests(authorize -> authorize - // H2 콘솔, Swagger UI 및 API 문서, Actuator 에 대한 접근 허용 - .requestMatchers("/h2-console/**", "/swagger-ui/**", "/v3/api-docs/**", "/actuator/prometheus").permitAll() + // H2 콘솔, Actuator 에 대한 접근 허용 + .requestMatchers("/h2-console/**", "/actuator/prometheus").permitAll() // 재학생 인증을 완료한 사용자 (ROLE_VERIFIED) .requestMatchers("/api/v1/accounts/register").hasRole("VERIFIED") diff --git a/src/main/java/com/smunity/server/global/security/config/SwaggerProperties.java b/src/main/java/com/smunity/server/global/security/config/SwaggerProperties.java new file mode 100644 index 0000000..e0ebb0c --- /dev/null +++ b/src/main/java/com/smunity/server/global/security/config/SwaggerProperties.java @@ -0,0 +1,14 @@ +package com.smunity.server.global.security.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "swagger") +@Data +public class SwaggerProperties { + + private String username; + private String password; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9669dbe..1598742 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -13,6 +13,10 @@ springdoc: tags-sorter: alpha operations-sorter: alpha +swagger: + username: ${SWAGGER_USERNAME} + password: ${SWAGGER_PASSWORD} + management: endpoints: web: