본문 바로가기
프로젝트

[1일차 / JAVA] Spring Security 설정

by maverick11471 2025. 3. 25.

Spring Security

  • 개념
    1. @EnableWebSecurity : Spring Security 활성화
    2. BCryptPasswordEncoder : BCryptPasswordEncorder로 평문인 비밀번호를 해시코드로 변경
    3. SecurityFilterChain : Spring Security 기본정책 커스텀 가능
      1. CSRF(Cross-Site Request Forgery): 사용자의 인증 정보를 가로채서 악의적인 요청을 보내는 공격.
        * 폼 기반 로그인에서는 유용하지만, JWT 토큰으로 로그인 할 때는 필요 없음(토큰을 직접 전송하기 때문에)
      2. httpBasic 비활성화 : 브라우저에서 기본적으로 제공하는 로그인 방식이나, JWT 인증 기반을 사용하기 때문에 불필요
      3. sessionManagement : Spring Security에서는 기본적으로 세션으로 로그인을 유지하나, JWT Token을 사용시에는 필요 없음.
      4. authorizeHttpRequests: 특정 엔드포인트는 인증 없이 사용가능 하나, 나머지 경로는 반드시 인증이 필요하다.
      5. addFilterAfter : jwtFilter 검증필터를 Spring Security 필터 체인에 추가
  • 왜? 인증, 권한 부여, CSRF 보호, 비밀번호 암호화, 세션 관리 등 보안 요구 사항을 효율적으로 처리해 주며, 이를 통해 애플리케이션을 외부 공격으로부터 안전하게 보호, Spring Security는 다양한 인증 및 권한 관리 기능을 제공하여 개발자가 보안을 손쉽게 구현
  • 단계 : Bean 총 3개
    1. 비밀번호 암호화 방식 설정(BCrypt)
    2. Cors 설정 방식 적용
    3. 기본 보안 설정(5) : csrf, httpbasic, sessionManagement, authorizeHttpRequests, addFilterAfter
package bibid.config;

import bibid.jwt.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
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.config.annotation.web.configurers.AbstractHttpConfigurer;
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 org.springframework.web.filter.CorsFilter;

import java.util.Arrays;

@Configuration  // 🅰️ Spring 설정 클래스로 등록
@EnableWebSecurity  // 🅰️ Spring Security 활성화
@RequiredArgsConstructor  // 🅰️ final 필드 자동 주입 생성자 생성 (Lombok)
public class SecurityConfiguration {
    private final JwtAuthenticationFilter jwtAuthenticationFilter;  // 🔧 JWT 검증 필터

    // [1] 비밀번호 암호화 방식 설정 (BCrypt)
    @Bean  // 🅰️ Spring Bean으로 등록
    public static PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();  // 🔧 BCrypt 해시 알고리즘 사용
    }

    @Bean  // 🅰️ Security 필터 체인 구성
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                // [2] CORS 설정 적용
                .cors(httpSecurityCorsConfigurer -> {
                    httpSecurityCorsConfigurer.configurationSource(corsConfigurationSource());  // 🔧 커스텀 CORS 설정 주입
                })
                
                // [3] 기본 보안 설정
                .csrf(AbstractHttpConfigurer::disable)  // 🔧 CSRF 보호 비활성화 (REST API 특성)
                .httpBasic(httpSecurityHttpBasicConfigurer -> 
                    httpSecurityHttpBasicConfigurer.disable()  // 🔧 HTTP Basic 인증 비활성화
                )
                .sessionManagement(httpSecuritySessionManagementConfigurer ->
                        httpSecuritySessionManagementConfigurer.sessionCreationPolicy(
                                SessionCreationPolicy.STATELESS  // 🔧 세션 사용 안 함 (JWT 사용 시 필수)
                        ))
                
                // [4] 엔드포인트 접근 권한 설정
                .authorizeHttpRequests(authorization -> {
                    authorization.requestMatchers(  // ✅ 공개 접근 허용 경로
                            "/swagger-ui.html",  // Swagger UI
                            "/swagger-ui/**",    // Swagger 리소스
                            "/v3/api-docs/**",    // API 문서 엔드포인트
                            "/members/**",        // 회원 관련 API
                    ).permitAll();
                    authorization.anyRequest().authenticated();  // 🔒 나머지 경로 인증 필수
                })
                
                // [5] 필터 추가
                .addFilterAfter(jwtAuthenticationFilter, CorsFilter.class)  // 🔧 CORS 처리 후 JWT 검증
                .build();
    }

    // [2] CORS 상세 설정
    @Bean  // 🅰️ CORS 정책 Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        // 🌐 교차 출처 리소스 공유 설정
        configuration.setAllowedOrigins(Arrays.asList(
                "http://localhost:3000"   // 로컬 개발 환경
        ));  
        configuration.setAllowedMethods(Arrays.asList(  // ✅ 허용 HTTP 메서드
                "GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"
        ));
        configuration.setAllowedHeaders(Arrays.asList("*"));  // ✅ 모든 헤더 허용
        configuration.setAllowCredentials(true);  // 🔄 쿠키/인증 헤더 전송 허용

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);  // 🌍 모든 경로에 적용
        return source;
    }
}

'프로젝트' 카테고리의 다른 글

[1일차 / JAVA] Cors 설정  (1) 2025.03.25