인프런 커뮤니티 질문&답변

호갱님의 프로필 이미지
호갱

작성한 질문수

스프링 시큐리티 OAuth2

oauth2 적용시 cors 에러

해결된 질문

작성

·

458

0

안녕하세요

디테일한 강의 어렵지만 조금씩 잘 보고 있습니다.

좋은 강의 만들어주셔서 감사합니다.

 

제가 실무에서 oauth2 로 google , naver 로그인 연동에 진행중에 있습니다.

spring boot 3.x 버전이고 kotlin 으로 진행중에 있습니다.

 

현재 cors 에러가 나서 검색하다가

https://www.inflearn.com/questions/1064449/authenticationentrypoint-%EB%A5%BC-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95%EB%90%9C-login%EC%9D%B4-%EC%95%84%EB%8B%8C-react-%EC%9B%B9-%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A1%9C-%EC%84%A4%EC%A0%95-%EC%8B%9C-cors-%EB%AC%B8%EC%A0%9C%EA%B0%80-%EC%A7%80%EC%86%8D%ED%95%B4%EC%84%9C-%EB%B0%9C%EC%83%9D%ED%95%A9

 

여기서

말씀하신

CorsConfigurationSource corsConfigurationSource()

적용해보았고

정말 많은 수정을 하였지만 계속 cors 에러가 나고 있는상황입니다.

현재 local 에서 작업테스트중이며

front : localhost:3000

backend : localhost:8080 현재 api 서버

입니다.

 

인증이 필요없는 페이지에서는 axios 로 호출된 데이터가 잘 호출이됩니다.

아래는 kotlin 으로만든 securityConfig 입니다.

혹시 추가할 사항이 있을까요?

 

봐주셔서 감사합니다.

( 별도의 WonCoinfig 클래스에 corsRegistry 도 추가되어 있습니다. )

 

package hurryup.hukbizibbackend.config

import hurryup.hukbizibbackend.service.CustomOAuth2UserService
import hurryup.hukbizibbackend.utils.JWTFilter
import hurryup.hukbizibbackend.utils.JWTUtil
import hurryup.hukbizibbackend.utils.OAuth2SuccessHandler
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.http.SessionCreationPolicy
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource
import org.springframework.web.cors.UrlBasedCorsConfigurationSource

@Configuration
@EnableWebSecurity
class SecurityConfig(
    private val customOAuth2UserService: CustomOAuth2UserService,
    private val oAuth2SuccessHandler: OAuth2SuccessHandler,
    private val jwtUtil: JWTUtil
) {

//
//    private fun configureCors(corsCustomizer: CorsConfigurer<HttpSecurity>) {
//        corsCustomizer.configurationSource(corsConfigurationSource())
//    }
//
//    @Bean
//    fun corsConfigurationSource(): CorsConfigurationSource {
//        println("corsConfigurationSource")
//        val configuration = CorsConfiguration()
//        configuration.allowedOrigins = listOf("http://localhost:3000")
//        //configuration.addAllowedOrigin("*")
//        configuration.allowedMethods = listOf("GET", "POST", "PUT", "DELETE", "OPTIONS")
//        //configuration.allowedHeaders = listOf("*")
//        configuration.allowedHeaders = listOf("Origin", "Content-Type", "Accept", "Authorization", "X-Requested-With", "X-XSRF-TOKEN", "X-Auth-Token", "X-Auth-Token-Expire", "X-Auth-Token-Refresh")
//        //configuration.exposedHeaders = listOf("Set-Cookie", "Authorization")
//        configuration.maxAge = 3600L
//        configuration.allowCredentials = true
//
//        return CorsConfigurationSource { configuration }
//    }

    @Bean
    fun corsConfigurationSource(): CorsConfigurationSource {
        val config = CorsConfiguration()
        config.allowCredentials = true

        config.allowedOrigins = listOf("http://localhost:3000")

        config.allowedMethods = listOf("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")

        config.allowedHeaders = listOf("*")

        config.exposedHeaders = listOf("*")

        val source: UrlBasedCorsConfigurationSource = UrlBasedCorsConfigurationSource()

        source.registerCorsConfiguration("/**", config)

        return source
    }



    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {

        http
            //.cors { configureCors(it) }
            .cors { it.configurationSource(corsConfigurationSource()) }



        http
            .csrf { it.disable() }

        http
            .formLogin { it.disable() }

        http
            .httpBasic { it.disable() }

        http
            .addFilterAfter(JWTFilter(jwtUtil), UsernamePasswordAuthenticationFilter::class.java)

        http
            .oauth2Login { oauth2 ->
                oauth2.userInfoEndpoint { endpoint ->
                    endpoint.userService(customOAuth2UserService)
                }
                    .successHandler(oAuth2SuccessHandler)
            }

        http
            .logout {
                it.deleteCookies("Authorization")   // 단순 쿠키삭제
                    // 이 메소드는 LogoutHandler 인터페이스를 구현한 CookieClearingLogoutHandler 객체를 로그아웃 핸들러로 추가합니다.
                    // CookieClearingLogoutHandler는 생성자에서 받은 쿠키 이름들을 로그아웃 시 삭제합니다.
                    // 이 메소드는 여러 개의 쿠키를 한 번에 삭제할 수 있으며, 추가적인 로그아웃 로직을 구현할 수 있습니다.
                    .addLogoutHandler(CookieClearingLogoutHandler("Authorization"))
            }

        http
            .authorizeHttpRequests { auth ->
                auth.requestMatchers("/", "/login", "/swagger-ui/**", "/v3/**","/api/v1/users/" +
                        "").permitAll()       // root 경로는 모두허용
                    .anyRequest().authenticated()               // 나머지는 인증 필요
            }


        http
            .sessionManagement { session ->
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            }

        return http.build()
    }


}

 

 

답변 1

-2

안녕하세요, 인프런 AI 인턴입니다. Changsu Woo님의 Spring Security와 OAuth2 적용 과정에서 발생하는 CORS 문제 관련하여 질문 주셨네요.

해당 문제와 매우 유사한 상황을 다룬 질문이 있습니다. authenticationEntryPoint를 기본 설정된 /login이 아닌 react 웹 페이지로 설정 시 cors 문제가 지속해서 발생합니다. 에서는 CORS 문제 해결과 관련된 다양한 접근 방법이 논의되고 있으며, 특정 설정 방법에 대한 지식공유자의 대답이 포함되어 있습니다.

문제의 핵심은 Spring Security를 사용하여 OAuth2 인증을 구현할 때, CORS(Cross-Origin Resource Sharing) 정책으로 인해 발생하는 접근 제어 문제를 해결하는 것입니다.

보안 설정에서 주요 포인트는 CorsConfigurationSource를 구성하는 부분입니다. CorsConfigurationSource는 Spring Security에서 CORS 요청을 처리할 때 사용하는 설정입니다. 예제에서는 http://localhost:3000에서 오는 모든 요청(/**)에 대해서 GET, POST, PUT, DELETE, PATCH, OPTIONS 메소드를 허용하고 있으며, 모든 헤더를 허용하고 있습니다. allowCredentials는 요청에서 쿠키를 포함시키기 위해 true로 설정되어 있습니다.

corsConfigurationSource() 메서드에서 반환되는 CorsConfigurationSource 객체는 UrlBasedCorsConfigurationSource를 사용하여 정의되며, 이는 Spring Security의 CORS 필터에 의해 사용됩니다.

그러나 문제가 지속된다면, CORS 정책 외에도 문제의 원인으로 고려해야 할 다른 설정이나 구성요소가 있을 수 있습니다. 예를 들어, OAuth2 로그인 후의 처리 과정, JWT 토큰 검증 로직, 세션 관리 설정 등이 올바르게 구성되었는지 확인이 필요합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

호갱님의 프로필 이미지
호갱

작성한 질문수

질문하기