CORS

介绍

出于安全的考虑,浏览器禁止ajax调用当前域之外的资源。例如,当你在一个选项卡上查看你的银行账户时,你可以在另一个标签页打开evil.com网站。来自evil.com的脚本不应该能够将AJAX请求发送到您的银行API(例如:取钱操作)

跨源资源共享(CORS)是由大多数浏览器实现的W3C规范,允许您以灵活的方式指定哪些跨域请求被授权,而不是使用诸如IFRAME或JSONP之类的安全性较低的小技巧。

SpringWebflux支持CORS。CORS请求包括选项方法preflight自动注册到处理器映射器中。使用CorsProcessor实现(默认为DefaultCorsProcessor)来处理CORS的preflight请求和拦截CORS的简单和实际请求,以便根据您提供的CORS配置添加相关的CORS响应头(例如:Access-Control-Allow-Origin)

注意:cookie在任何情况下是默认不被允许的。以避免增加web攻击风险(例如,通过暴露敏感的用户特定的信息,如CSRF令牌)。将证书Credentialsproperty设置为true,允许cookie开启

@CrossOrigin

可以在@RequestMapping注释处理程序方法中添加一个@CrossOrigin注释,以便启用CORS。

@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin
    @GetMapping("/{id}")
    public Mono<Account> retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public Mono<Void> remove(@PathVariable Long id) {
        // ...
    }
}

还可以控制整个控制器

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @GetMapping("/{id}")
    public Mono<Account> retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public Mono<Void> remove(@PathVariable Long id) {
        // ...
    }
}

在上面的示例中,retrieve()和remove()处理方法都启用了CORS支持,当然你还可以看到如何使用@CrossOrigin属性自定义CORS配置。甚至可以同时使用控制器级和方法级的CORS配置;然后Spring将结合两个注释的属性来创建合并的CORS配置。

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://domain2.com")
    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Java配置

除了精细的、基于注解的配置之外,您还可能需要定义一些全局的CORS配置。这类似于使用过滤器。但是可以在Spring WebFlux中声明,并结合细粒度的@CrossOrigin。默认情况下,GET, HEAD, 和POST这些方法是允许跨域的

整个应用跨域设置

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

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

可以简单的更改属性,并且只将该CORS配置应用到特定的路径模式:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("http://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(true).maxAge(3600);
    }
}

CORS WebFilter

你可以通过内置的CorsWebFilter来应用CORS支持,这与功能端点非常类似。

要配置过滤器,您可以声明一个CorsWebFilter bean并将CorsConfigurationSource传递给它的构造函数:

@Bean
CorsWebFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("http://domain1.com");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);

    return new CorsWebFilter(source);
}

你可以轻松的让GET, HEAD和POST请求通过编写

@Bean
CorsWebFilter corsFilter() {
    return new CorsWebFilter(exchange -> new CorsConfiguration().applyPermitDefaultValues());
}

高级定制

CorsConfiguration允许您指定如何处理CORS请求,并且可以通过多种方式实现。

  • AbstractHandlerMapping#setCorsConfigurations()允许指定映射到路径模式(比如/ api/* *)的CorsConfiguration实例的映射。
  • 子类可以提供自己的CorsConfiguration覆盖theAbstractHandlerMapping # getCorsConfiguration(Object,ServerWebExchange)方法。

  • 处理程序可以实现CorsConfigurationSource接口,以便为每个请求提供一个CorsConfiguration实例。

results matching ""

    No results matching ""