For me (using same technologies like you), creating custom filter component (CorsFilter) worked the best out of all other options:
Example of my configuration:
@Component
class CorsFilter: WebFilter {
@Value("\${cors.allowed_origin}")
lateinit var allowedOrigin: String
override fun filter(ctx: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
ctx.response.headers.add("Access-Control-Allow-Origin", allowedOrigin)
ctx.response.headers.add("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS")
ctx.response.headers.add("Access-Control-Allow-Credentials", "true")
ctx.response.headers.add("Access-Control-Allow-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range, Authorization")
return when {
ctx.request.method == HttpMethod.OPTIONS -> {
ctx.response.headers.add("Access-Control-Max-Age", "1728000")
ctx.response.statusCode = HttpStatus.NO_CONTENT
Mono.empty()
}
else -> {
ctx.response.headers.add("Access-Control-Expose-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range")
chain.filter(ctx)
}
}
}
}
note: allowedOrigin
variable is taken from applications.properties files