zoukankan      html  css  js  c++  java
  • SpringMVC对于跨域访问的支持

    原文地址:http://docs.spring.io/spring/docs/5.0.0.RC2/spring-framework-reference/web.html#mvc-introduction

    一、简介

    出于安全原因,浏览器禁止Ajax调用与当前资源不同源的外部资源。例如:如果你正在一个窗口检查你的银行账户,那你可能会遇到这样的错误:com网站在另一个窗口打开。这是一个错误的脚本。因为com不应该让Ajax使用你的凭证请求到你的银行API(例如:从你的银行账户提现)。

    Cross-origin resource sharing(CORS) 是一个大多数浏览器对W3C规范的实现,它允许你灵活的对具体的跨域请求进行授权,而不是使用一些不太安全或者不太稳固的手段,例如:IFRAME 和 JSONP。

    从Spring Framework4.2以来,CORS支持开箱即用。CORS请求(包括一个带有OPTIONS预检的方法)被动态的分发到各种已经注册的HandlerMappings。他们处理CORS的预检请求,拦截简单的和精确的CORS请求。这一切都归功于CorsProcessor实现(默认为DefaultCorsProcessor)了根据您提供的CORS配置去添加相关的CORS响应头(如Access-Control-Allow-Origin)。

    备注:由于CORS请求被动态分发,所以,你不必去改变DispatcherServlet、dispatchOptionsRequest的初始化参数。推荐使用默认的参数值(false)。

    二、在Controller方法中配置CORS

    你可以添加一个@CrossORigin注解到你的@RequestMapping注解上,去为一个方法添加CORS授权。通过默认的@CorssOrigin注解,它允许所有的同源和基于HTTP协议的调用:

    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
            @CrossOrigin
            @RequestMapping("/{id}")
            public Account retrieve(@PathVariable Long id) {
                    // ...
            }
    
            @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
            public void remove(@PathVariable Long id) {
                    // ...
            }
    }

    它也可以为整个Controller开启CORS授权:

    @CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
            @RequestMapping("/{id}")
            public Account retrieve(@PathVariable Long id) {
                    // ...
            }
    
            @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
            public void remove(@PathVariable Long id) {
                    // ...
            }
    }
    在上面的CORS授权实例中,都是通过操作retrieve()和remove()方法。你还可以通过使用@CrossOrigin属性去定制CORS。

    你甚至可以同时使用基于Controller和基于method方法的CORS配置。Spring将合成它们各自的属性去创建一个完整的CORS配置:

    @CrossOrigin(maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
            @CrossOrigin("http://domain2.com")
            @RequestMapping("/{id}")
            public Account retrieve(@PathVariable Long id) {
                    // ...
            }
    
            @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
            public void remove(@PathVariable Long id) {
                    // ...
            }
    }

    三、全局的CORS配置

    除了基于注解的细粒度的配置,你可能还需要定义一些全局的CORS配置。这有点类似于filter,可以使用SpringMVC的声明去做,并且组合细粒度的@CrossORigin配置。默认同源,和GET、HEAD、POST方法被允许CORS调用

    1,JavaConfig

    简单为整个application应用CORS:

    @Configuration
    @EnableWebMvc
    public class WebConfig implements WebMvcConfigurer {
    
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**");
            }
    }
    你也可以很容易的修改任何属性,以及将此CORS配置到任意路径的模式:

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

    2,XML 命名空间

    下面极简单的XML配置将为所有的/**路径请求模式开启CORS授权(同样默认的属性配置,同上面提到的JavaConfig实例):

    <mvc:cors>
            <mvc:mapping path="/**" />
    </mvc:cors>

    也可以通过定制属性去声明几个CORS授权配置:

    <mvc:cors>
    
            <mvc:mapping path="/api/**"
                    allowed-origins="http://domain1.com, http://domain2.com"
                    allowed-methods="GET, PUT"
                    allowed-headers="header1, header2, header3"
                    exposed-headers="header1, header2" allow-credentials="false"
                    max-age="123" />
    
            <mvc:mapping path="/resources/**"
                    allowed-origins="http://domain1.com" />
    
    </mvc:cors>

    四、高级定制

    CorsConfiguration允许你指定CORS请求被处理的方式:允许同源、headers、methods等。它可以由几种不同的方式配置:

    1,AbstractHandlerMapping#setCorsConfiguration()允许指定映射路径模式(如/ api / **)的几个CorsConfiguration实例的Map。

    2,子类可以通过覆盖AbstractHandlerMapping#getCorsConfiguration(Object,HttpServletRequest)方法来提供自己的CorsConfiguration。
    3,处理程序可以实现CorsConfigurationSource接口(像ResourceHttpRequestHandler现在这样做),以便为每个请求提供一个CorsConfiguration实例

    五、基于Filter的CORS支持

    为了支持基于过滤器安全框架(如Spring Security)的CORS,或者与其他不支持本地CORS的库一起支持CORS,Spring Framework还提供了一个CorsFilter。代替使用@CrossOrigin或WebMvcConfigurer#addCorsMappings(CorsRegistry),您需要注册一个自定义过滤器,定义如下:

    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    public class MyCorsFilter extends CorsFilter {
    
            public MyCorsFilter() {
                    super(configurationSource());
            }
    
            private static UrlBasedCorsConfigurationSource configurationSource() {
                    CorsConfiguration config = new CorsConfiguration();
                    config.setAllowCredentials(true);
                    config.addAllowedOrigin("http://domain1.com");
                    config.addAllowedHeader("*");
                    config.addAllowedMethod("*");
                    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                    source.registerCorsConfiguration("/**", config);
                    return source;
            }
    }
    你需要确保CorsFilter在其他filter之前执行。

  • 相关阅读:
    二维树状数组(模板)
    3033太鼓达人
    2503相框
    Ant Trip(画几笔)
    [ZJOI2004]嗅探器
    [USACO06JAN]冗余路径Redundant Paths(缩点)
    P3806 【模板】点分治1
    P4149 [IOI2011]Race
    P2634 [国家集训队]聪聪可可
    P4178 Tree
  • 原文地址:https://www.cnblogs.com/hhx626/p/7534583.html
Copyright © 2011-2022 走看看