Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 1057 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Enable CORS in Spring 5 Webflux?

#1
How to enable **CORS** in a Spring 5 Webflux Project?

I cannot find any proper documentation.
Reply

#2
@Configuration
public class WebFluxConfig {

@Bean
public WebFluxConfigurer corsConfigurer() {
return new WebFluxConfigurerComposite() {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*")
.allowedMethods("*");
}
};
}
}

which corresponds to:

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {

@Override
public void addCorsMappings(CorsRegistry registry) {

for spring mvc.
Reply

#3
I had success with this custom filter:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;

import reactor.core.publisher.Mono;


@Configuration
public class CorsConfiguration {

private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN";
private static final String ALLOWED_METHODS = "GET, PUT, POST, DELETE, OPTIONS";
private static final String ALLOWED_ORIGIN = "*";
private static final String MAX_AGE = "3600";

@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Max-Age", MAX_AGE);
headers.add("Access-Control-Allow-Headers",ALLOWED_HEADERS);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}

}

and `org.springframework.boot:spring-boot-starter-web` should not be included as dependency - filter does not work with it.
Reply

#4
Here is another solution with the Webflux Configurer.

Side Note: Its Kotlin Code (copied from my project) but you can easily translate that to Java Code.

@Configuration
@EnableWebFlux
class WebConfig: WebFluxConfigurer
{
override fun addCorsMappings(registry: CorsRegistry)
{
registry.addMapping("/**")
.allowedOrigins("*") // any host or put domain(s) here
.allowedMethods("GET, POST") // put the http verbs you want allow
.allowedHeaders("Authorization") // put the http headers you want allow
}
}
Reply

#5
Thanks to @Dachstein, replacing WebMvc configs with Webflux is the correct way of adding global CORS Config here.

@Configuration
@EnableWebFlux
public class CORSConfig implements WebFluxConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*");
}
}
Reply

#6
Here is a link to the official documentation

[To see links please register here]


There are 3 main options

1) Using the @CrossOrigin annotation on a rest controller - it can be used at class and/or method level

2) Implement the addCorsMapping method from the WebFluxConfigurer - it gives you an hook into the global CorsRegistry object

3) Define a CorsWebFilter component - good choice for functional endpoints

Please look at the docs, are well explained.

Personally I use the third option when I want to allow cors while developing and I have decoupled the backend from the frontend module.

Imagine that you have webflux on a backend module while on the frontend you have a react or angular app. While developing the frontend features you might want to use webpack-dev-server for hot reloading while still running the backend on netty - the port will be different and this will cause CORS problem. With the third option you can easily link the @Component to @Profile("dev") so that when you deploy in prod CORS are enabled.
Reply

#7
If someone wants a Kotlin version of Zufar's answer(works like a charm with webflux routing functions) without additionally figuring out how Kotlin's SAM conversions work, here is the code:

@Bean
fun corsFilter(): WebFilter {
return WebFilter { ctx, chain ->
val request = ctx.request
if (CorsUtils.isCorsRequest(request)) {
val response = ctx.response
val headers = response.headers
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN)
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS)
headers.add("Access-Control-Max-Age", MAX_AGE)
headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS)
if (request.method === HttpMethod.OPTIONS) {
response.statusCode = HttpStatus.OK
return@WebFilter Mono.empty<Void>()
}
}
chain.filter(ctx)
}
}

**UPDATE**
As I started testing it I found one problem with this solution. It's Ok if you really want to allow all methods. But imagine you want to only allow `POST` and `OPTIONS`, for example. And the browser is trying to send `PUT`.

Then a preflight response will basically say "hey, I can only serve POST and OPTIONS, but my HTTP status will be `OK` if you give me a request with `Access-Control-Request-Method=PUT`". It should be `403 Forbidden` however.
What's more, most of those headers, like `Access-Control-Allow-Methods` should only be added to preflight requests, not all `CORS` requests.
Solution:

@Bean
fun corsWebFilter(): CorsWebFilter {
val corsConfig = CorsConfiguration()
corsConfig.allowedOrigins = Arrays.asList(ALLOWED_ORIGINS)
corsConfig.maxAge = MAX_AGE.toLong()
//Notice it's singular. Can't be comma separated list
corsConfig.addAllowedMethod(ALLOWED_METHOD)
corsConfig.addAllowedHeader(ALLOWED_HEADER)

val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration(MATCH_ALL_PATH_SEGMENTS, corsConfig)

return CorsWebFilter(source)
}
where

const val MATCH_ALL_PATH_SEGMENTS = "/**"
Reply

#8
While @Dachstein's answer is correct it still may not work if you have Security enabled. You can read the documentation about this here

[To see links please register here]

but the provided code may not be enough because of missing `applyPermitDefaultValues()` method.

If so, try the code below:

```java
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.applyPermitDefaultValues();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));
configuration.setAllowedMethods(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
```
Reply

#9
If using spring webflux security following snippet works

protected ServerHttpSecurity applyCors(ServerHttpSecurity http) {
return http.cors().configurationSource(urlBasedCorsConfigurationSource()).and();
}

private UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.applyPermitDefaultValues();
// corsConfiguration.setAllowCredentials(true);
corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList("*"));
corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
UrlBasedCorsConfigurationSource ccs = new UrlBasedCorsConfigurationSource();
ccs.registerCorsConfiguration("/**", corsConfiguration);
return ccs;
}
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through