当前位置: 首页 > 知识库问答 >
问题:

Spring WebFlux Kotlin OAuth2 CORS

史修明
2023-03-14

下面是配置。。。

我的后端是localhost:8080,前端是localhost:3000。后端的身份验证仅通过OAuth2处理。基本上,前端用户单击“使用Spotify登录”,会被重定向到处理OAuth2的后端,然后重定向回前端。所有后续请求都来自前端到后端。(前端位于Next.JS BTW中)

这是我的问题。。。

如果我没有经过身份验证,任何对我后端的请求都会抛出一个CORS错误。(如果我通过了身份验证,它将按预期工作)。因此,GET/users/{id},在未登录时,返回CORS,而不仅仅是一个普通的401。这没关系,因为我可以解决它,但是现在由于CORS,我无法向endpoint发出PUT请求,即使在登录时也是如此。。。我尝试了@CrossOrigin注释,但这没有帮助。我也试过了。cors()。在SecurityConfig中禁用(),但是我仍然会在前端引发CORS错误。。。

以下是我用于安全/WebFlux的内容:

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
       </dependency>
       <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-client</artifactId>
            <version>5.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.3.4.RELEASE</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

这是我的CorsConfig:

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter("/*")
class CorsConfig: WebFluxConfigurer {
    override fun addCorsMappings(registry: CorsRegistry) {
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
                .allowCredentials(true)
        super.addCorsMappings(registry)
    }
}

这是我的安全配置


@EnableWebFluxSecurity
class SecurityConfig(
        @Qualifier("globalErrorHandler")
        private val exceptionHandler: WebExceptionHandler,
        private val authenticationFailureHandler: ServerAuthenticationFailureHandler,
        private val authenticationSuccessHandler: AuthenticationSuccessHandler,
        private val authorizationRequestResolver: ServerOAuth2AuthorizationRequestResolver,
        private val logoutSuccessHandler: LogoutSuccessHandler
) {
    @Bean
    fun securityFilterChain(
            httpSecurity: ServerHttpSecurity
    ): SecurityWebFilterChain = httpSecurity
            .authorizeExchange()
            .pathMatchers("/login", "/register", "/logout").permitAll()
            .anyExchange().authenticated()
            .and()
            .cors().disable()
            .exceptionHandling(::withConfiguration)
            .oauth2Login(::withConfiguration)
            .logout(::withConfiguration)
            .csrf().disable()
            .build()

    fun withConfiguration(spec: ServerHttpSecurity.ExceptionHandlingSpec): Unit =
            spec.accessDeniedHandler(exceptionHandler::handle)
                    .authenticationEntryPoint(exceptionHandler::handle)
                    .run {}

    fun withConfiguration(spec: ServerHttpSecurity.OAuth2LoginSpec): Unit =
            spec.authenticationFailureHandler(authenticationFailureHandler)
                    .authenticationSuccessHandler(authenticationSuccessHandler)
                    .authorizationRequestResolver(authorizationRequestResolver)
                    .run { }

    fun withConfiguration(spec: ServerHttpSecurity.LogoutSpec): Unit =
            spec.logoutUrl("/logout")
                    .logoutSuccessHandler(logoutSuccessHandler)
                    .run { }
}

如果您需要更多信息,请随时询问。

共有1个答案

公良云
2023-03-14

这是我的解决方案,我需要添加以下内容:

    fun corsConfigurationSource(): CorsConfigurationSource {
        val cors = CorsConfiguration()
        cors.allowedOrigins = List.of("*")
        cors.allowedMethods = List.of("*")
        cors.allowedHeaders = List.of("*")
        cors.allowCredentials = true
        cors.maxAge = 3600L
        val source = UrlBasedCorsConfigurationSource()
        source.registerCorsConfiguration("/**", cors)
        return source
    }

然后,在我的SecurityWebFilterChain中,我需要让Cors使用我的配置:

    @Bean
    fun securityFilterChain(
            httpSecurity: ServerHttpSecurity
    ): SecurityWebFilterChain = httpSecurity
            .cors(::withConfiguration)
            .csrf().disable()
            .authorizeExchange()
            .pathMatchers("/login", "/register", "/logout").permitAll()
            .anyExchange().authenticated()
            .and()
            .exceptionHandling(::withConfiguration)
            .oauth2Login(::withConfiguration)
            .logout(::withConfiguration)
            .build()

而::withConfiguration解决方案是:

    fun withConfiguration(spec: ServerHttpSecurity.CorsSpec): Unit =
            spec.configurationSource(corsConfigurationSource())
                    .run { }
 类似资料:

相关问答

相关文章

相关阅读