Spring Security - 2 - Bean 등록

일단 필요한 전체코드 - 아래는 설명입니다.

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        // 허용할 도메인 설정 (명시적으로 설정)
        configuration.setAllowedOrigins(Arrays.asList("<http://localhost:3000>", "<http://localhost:8000>"));

        // 허용할 HTTP 메서드
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));

        // 허용할 헤더
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));

        // 인증 정보 허용 (쿠키나 인증정보)
        configuration.setAllowCredentials(true);

        // 노출할 헤더
        configuration.setExposedHeaders(Arrays.asList("Authorization", "Content-Type"));

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

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)  // CSRF 비활성화
                .headers(headers -> headers
                        .frameOptions(frameOptions -> frameOptions.disable())  // X-Frame-Options 비활성화
                )
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))  // CORS 설정 적용
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()  // Preflight 요청 허용
                        .anyRequest().permitAll()  // 모든 요청 허용
                )
                .addFilterBefore(corsLoggingFilter(), UsernamePasswordAuthenticationFilter.class);  // 필터 체인에 추가

        return http.build();
    }

    // CORS에 걸린 도메인을 로그로 남기는 필터
    @Bean
    public Filter corsLoggingFilter() {
        return new Filter() {
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {
                // 필터 초기화
            }

            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException {
                HttpServletRequest httpRequest = (HttpServletRequest) request;

                // CORS 관련 요청인지 확인
                if (CorsUtils.isCorsRequest(httpRequest)) {
                    String origin = httpRequest.getHeader("Origin");
                    logger.info("CORS 요청 - Origin: {}", origin);
                }

                // 필터 체인 진행
                chain.doFilter(request, response);
            }

            @Override
            public void destroy() {
                // 필터 종료 처리
            }
        };
    }

저는 일반적으로 3개의 빈을 커스터 마이징해 사용하고 있습니다.

corsConfigurationSource

이 메서드는 Spring 애플리케이션에서 CORS(Cross-Origin Resource Sharing) 설정을 정의하기 위해 사용됩니다. Spring Security 또는 일반 Spring Web 애플리케이션에서 다른 도메인에서의 HTTP 요청을 제어하기 위한 설정입니다.


코드 세부 설명

1. 메서드 선언:

  • @Bean: Spring 컨테이너에 이 메서드의 리턴 값을 Bean으로 등록합니다. 이를 통해 Spring Security 또는 WebMvc 설정에서 이 Bean을 참조하여 CORS 구성을 사용합니다.
  • CorsConfigurationSource: Spring에서 CORS 설정을 적용하기 위해 사용하는 인터페이스입니다.

2. CorsConfiguration 객체 생성:

  • CorsConfiguration: CORS 설정을 정의할 수 있는 객체입니다. 이 객체에서 허용할 도메인, HTTP 메서드, 헤더 등을 설정합니다.

3. 허용할 도메인 설정 (AllowedOrigins):

  • 설명: 외부에서 이 애플리케이션에 접근할 수 있는 도메인을 명시합니다.
    • http://localhost:3000: React와 같은 프론트엔드 개발 환경에서 주로 사용됩니다.
    • http://localhost:8000: 또 다른 허용 도메인.
  • CORS 규칙은 기본적으로 도메인 간 요청을 차단하므로, 명시적으로 허용할 도메인을 지정해야 합니다.

4. 허용할 HTTP 메서드 (AllowedMethods):

  • 설명: 허용할 HTTP 요청 메서드를 설정합니다.
    • GET, POST, PUT, DELETE: 주로 사용되는 메서드.
    • OPTIONS: 브라우저가 CORS 요청 전에 보내는 사전 요청(Preflight Request) 메서드입니다.

5. 허용할 헤더 (AllowedHeaders):

  • 설명: 클라이언트에서 요청 시 사용할 수 있는 HTTP 헤더를 지정합니다.
    • Authorization: 인증 정보를 포함한 요청을 허용.
    • Content-Type: 요청 본문의 데이터 형식을 지정하는 헤더를 허용.

6. 인증 정보 허용 (AllowCredentials):

  • 설명: 클라이언트에서 보낸 쿠키, 세션, 인증 정보를 허용할지 여부를 설정합니다.
    • true: 인증 정보가 포함된 요청을 허용합니다.

7. 노출할 헤더 (ExposedHeaders):

  • 설명: 클라이언트가 응답에서 접근할 수 있는 헤더를 명시적으로 지정합니다.
    • 예: 서버가 Authorization 헤더를 응답에 포함했다면, 이를 클라이언트에서 읽을 수 있게 설정.

8. URL 패턴에 CORS 설정 적용:

  • UrlBasedCorsConfigurationSource: URL 패턴에 따라 CORS 설정을 적용하는 클래스입니다.
  • registerCorsConfiguration: 특정 경로(/**)에 위에서 정의한 CORS 설정을 등록합니다.
    • /**: 모든 URL 경로에 대해 설정 적용.

securityFilterChain

Spring Security에서 SecurityFilterChain을 정의하며, HTTP 요청에 대한 보안 규칙과 필터 체인을 설정합니다. 최신 Spring Security 방식으로 보안 구성을 설정하기 위해 사용됩니다.

세부 코드 설명:

1. 메서드 선언:

  • @Bean: 이 메서드가 반환하는 SecurityFilterChain 객체를 Spring 컨테이너에서 관리합니다.
  • SecurityFilterChain: HTTP 요청에 대한 보안 필터 체인을 구성하는 객체입니다.
  • HttpSecurity: Spring Security의 보안 설정 API를 제공하는 핵심 클래스입니다.

2. CSRF 비활성화:

  • 설명: CSRF(Cross-Site Request Forgery) 보호를 비활성화합니다.
    • 일반적으로 REST API 서버에서는 CSRF 보호가 필요 없으므로 비활성화합니다.

3. X-Frame-Options 비활성화:

  • 설명: 브라우저의 X-Frame-Options 헤더 설정을 비활성화합니다.
    • 사용 목적: HTML <iframe> 요소를 사용할 때 차단되지 않도록 하기 위함.
    • 예: H2 데이터베이스 콘솔처럼 iframe을 사용하는 UI를 지원하려는 경우.

4. CORS 설정 적용:

  • 설명: 미리 정의된 CORS 정책(corsConfigurationSource() 메서드)을 적용합니다.
    • CORS 설정은 다른 도메인에서 서버에 요청할 때의 규칙을 정의합니다.

5. Preflight 요청 허용:

  • 설명: 브라우저가 Preflight 요청(HTTP OPTIONS)을 보내는 경우 인증 없이 허용합니다.
    • Preflight 요청은 CORS 요청 전에 브라우저가 서버와 통신하기 위해 보내는 사전 요청입니다.

6. 모든 요청 허용:

  • 설명: 모든 요청을 인증 없이 허용합니다.
    • 개발 환경에서 보안을 최소화하거나, 외부 보안 장치로 보호되는 API의 경우 사용됩니다.
    • 실제 프로덕션 환경에서는 더 구체적인 인증 및 권한 설정이 필요합니다.

7. Custom Filter 추가:

  • 설명: 사용자 정의 필터(corsLoggingFilter())를 Spring Security의 기본 필터 체인에 추가합니다.
    • UsernamePasswordAuthenticationFilter 앞에 위치합니다.
    • 사용 목적: CORS 관련 요청을 로깅하거나 추가 처리를 하기 위한 필터를 삽입합니다.

corsLoggingFilter

Spring Filter를 정의하며, HTTP 요청 중 CORS 관련 요청을 로깅하기 위해 사용됩니다. 클라이언트에서 들어오는 CORS 요청의 Origin 헤더 값을 확인하고, 이를 로깅합니다.

주요 동작 설명:

1. 메서드 선언:

  • @Bean: 이 메서드의 반환 객체를 Spring 컨테이너에서 관리하는 Bean으로 등록합니다.
  • Filter: Java EE에서 제공하는 인터페이스로, HTTP 요청/응답 처리를 가로채거나 로직을 추가할 수 있습니다.

2. Filter 인터페이스 익명 구현체:

  • 익명 클래스를 사용해 Filter 인터페이스를 구현합니다.
  • init, doFilter, destroy 메서드를 오버라이드하여 필터 동작을 정의합니다.

3. init(FilterConfig filterConfig)

  • 설명: 필터 초기화 시 호출됩니다.
  • 사용 예: 필터가 동작하는 데 필요한 리소스나 설정을 초기화할 수 있습니다.
  • 현재 구현에서는 특별한 초기화 작업을 수행하지 않습니다.

4. doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

  • doFilter의 역할:
    • 요청/응답을 가로채 필요한 처리를 수행한 후, 체인의 다음 필터로 요청을 전달합니다.
    • 이 메서드는 필터의 핵심 동작을 정의합니다.
  • 동작 설명:
    1. 요청 객체를 HttpServletRequest로 캐스팅.
    2. CORS 요청인지 확인:
      • CorsUtils.isCorsRequest(httpRequest)를 사용하여 요청이 CORS 관련 요청인지 검사합니다.
    3. Origin 헤더 로깅:
      • 요청의 Origin 헤더 값을 로깅하여 CORS 요청의 출처를 기록합니다.
    4. 체인 진행:
      • chain.doFilter(request, response)를 호출하여 요청을 필터 체인의 다음 단계로 전달합니다.

5. destroy()

  • 설명: 필터가 종료될 때 호출됩니다.
  • 사용 예: 필터 동작에 사용된 리소스를 정리하거나 종료 작업을 수행합니다.
  • 현재 구현에서는 특별한 종료 작업을 수행하지 않습니다.

'Spring - Spring Boot' 카테고리의 다른 글

Spring - Spring Boot - Swagger 설정하기  (0) 2024.12.12
Spring Security - 1 - 설정  (2) 2024.12.04