Java 在Spring5WebFlux中启用CORS?
如何在Spring5WebFlux项目中启用CORS 我找不到任何适当的文件Java 在Spring5WebFlux中启用CORS?,java,spring,cors,spring-webflux,Java,Spring,Cors,Spring Webflux,如何在Spring5WebFlux项目中启用CORS 我找不到任何适当的文件 @Configuration public class WebFluxConfig { @Bean public WebFluxConfigurer corsConfigurer() { return new WebFluxConfigurerComposite() { @Override public void addCorsMapp
@Configuration
public class WebFluxConfig {
@Bean
public WebFluxConfigurer corsConfigurer() {
return new WebFluxConfigurerComposite() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*")
.allowedMethods("*");
}
};
}
}
对应于:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
对于spring mvc。我成功地使用了此自定义筛选器:
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);
};
}
}
和
org.springframework.boot:springbootstarterweb
不应作为依赖项包括在内-过滤器不能使用它。这里是Webflux配置器的另一个解决方案
旁注:它的Kotlin代码(复制自我的项目),但您可以轻松地将其转换为Java代码
@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
}
}
多亏了@Dachstein,用Webflux替换WebMvc配置是在此处添加全局CORS配置的正确方法
@Configuration
@EnableWebFlux
public class CORSConfig implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*");
}
}
这里是官方文件的链接 有3个主要选项 1) 在rest控制器上使用@CrossOrigin注释-它可以在类和/或方法级别使用 2) 从WebFluxConfigure实现addCorsMapping方法-它为您提供了一个全局CorsRegistry对象的挂钩 3) 定义CorsWebFilter组件-功能端点的最佳选择 请看这些文件,解释得很清楚 就我个人而言,当我想在开发过程中允许cors,并且我已经将后端与前端模块解耦时,我会使用第三个选项
假设您在后端模块上有webflux,而在前端有react或angular应用程序。在开发前端功能时,您可能希望在netty上运行后端的同时使用webpack dev server进行热重新加载-端口将不同,这将导致CORS问题。使用第三个选项,您可以轻松地将@Component链接到@Profile(“dev”),以便在prod CORS中部署时启用。如果有人想要Kotlin版本的Zufar答案(与webflux路由功能类似),而无需另外了解Kotlin的SAM转换是如何工作的,下面是代码:
@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)
}
}
在哪里
虽然@Dachstein的答案是正确的,但如果启用了安全性,它仍然可能不起作用。您可以在此处阅读相关文档,但提供的代码可能不够,因为缺少
applyPermitDefaultValues()
方法
如果是,请尝试以下代码:
@Bean
CorsConfiguration源CorsConfiguration源(){
CorsConfiguration配置=新的CorsConfiguration();
applyPermitDefaultValues();
configuration.setAllowedOriginates(Arrays.asList(“http://localhost:8081"));
configuration.setAllowedMethods(Arrays.asList(“*”);
UrlBasedCorsConfigurationSource=新的UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(“/**”,配置);
返回源;
}
您在控制器上尝试过@CrossOrigin(origins=“*”)吗?谢谢您的回复。。。我将在本周末试用。我已经尝试了spring cloud starter gateway(它使用spring 5 webflux)的答案-spring webflux中的非功能模型没有成功如果使用Netty和经典servlet过滤器,而不使用上述功能模型过滤器,实现类似过滤器的功能的推荐方法是什么?@ROCKY,我在netty中检查了这个例子——它起作用了。我想你可以在控制器中使用非功能模型,它会工作的(不过我还没有尝试过)。在netty中,这对我不起作用。选项仍然抛出CORS失败。谢谢你的回答,它救了我一天。我在这一天找到了这个链接!感谢您可以通过使用代理轻松解决Web包开发服务器端口与netty端口之间的问题。看见那时就不需要CORS了。如果我正确理解了你的问题?这个问题在启用cors auth的情况下对我有效。只为headersconfiguration.setAllowedHeaders(List.of(“*”)添加了一行额外的标题代码>这是我看到的解决这个问题的唯一方法,但它对我不起作用。标题只是没有添加到响应中。调用此重写的方法,如调试器所示。除此之外,您还有其他配置吗?@HaventCheck您能解决问题吗?在使用Spring Hateoas和@EnableHypermediaSupport时不起作用-从WebFluxConfiger扩展后不再添加链接。
@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)
}
const val MATCH_ALL_PATH_SEGMENTS = "/**"