SpringBoot跨域加SpringSecurity就失效( 二 )


@RestControllerclass HelloController {@GetMapping("hello")@CrossOrigin(origins = ["http://localhost:8080"])fun hello(): String {return "Hello, CORS!"}}3.2 实现 WebMvcConfigurer.addCorsMappings 方法WebMvcConfigurer 是一个接口 , 它同样来自于 Spring Web 。 我们可以通过实现它的 addCorsMappings 方法来针对全局 API 配置 CORS 规则:
@Configuration@EnableWebMvcclass MvcConfig: WebMvcConfigurer {override fun addCorsMappings(registry: CorsRegistry) {registry.addMapping("/hello").allowedOrigins("http://localhost:8080")}}3.3 注入 CorsFilterCorsFilter 同样来自于 Spring Web , 但是实现 WebMvcConfigurer.addCorsMappings 方法并不会使用到这个类 , 具体原因我们后面来分析 。 我们可以通过注入一个 CorsFilter 来使用它:
@Configurationclass CORSConfiguration {@Beanfun corsFilter(): CorsFilter {val configuration = CorsConfiguration()configuration.allowedOrigins = listOf("http://localhost:8080")val source = UrlBasedCorsConfigurationSource()source.registerCorsConfiguration("/hello", configuration)return CorsFilter(source)}}注入 CorsFilter 不止这一种方式 , 我们还可以通过注入一个 FilterRegistrationBean 来实现 , 这里就不给例子了 。
在仅仅引入 Spring Web 的情况下 , 实现 WebMvcConfigurer.addCorsMappings 方法和注入 CorsFilter 这两种方式可以达到同样的效果 , 二选一即可 。 它们的区别会在引入 Spring Security 之后会展现出来 , 我们后面再来分析 。
4、Spring Security 中的配置在引入了 Spring Security 之后 , 我们会发现前面的方法都不能正确的配置 CORS , 每次 preflight request 都会得到一个 401 的状态码 , 表示请求没有被授权 。 这时 , 我们需要增加一点配置才能让 CORS 正常工作:
【SpringBoot跨域加SpringSecurity就失效】@Configurationclass SecurityConfig : WebSecurityConfigurerAdapter() {override fun configure(http: HttpSecurity?) {http?.cors()}}或者 , 干脆不实现 WebMvcConfigurer.addCorsMappings 方法或者注入 CorsFilter, 而是注入一个 CorsConfigurationSource, 同样能与上面的代码配合 , 正确的配置 CORS:
@Beanfun corsConfigurationSource(): CorsConfigurationSource {val configuration = CorsConfiguration()configuration.allowedOrigins = listOf("http://localhost:8080")val source = UrlBasedCorsConfigurationSource()source.registerCorsConfiguration("/hello", configuration)return source}到此 , 我们已经看过了几种典型的例子了 , 我们接下来看看 Spring 到底是如何实现 CORS 验证的 。
5、这些配置有什么区别我们会主要分析实现 WebMvcConfigurer.addCorsMappings 方法和调用 HttpSecurity.cors 方法这两种方式是如何实现 CORS 的 , 但在进行之前 , 我们要先复习一下 Filter 与 Interceptor 的概念 。
5.1 Filter 与 Interceptor
SpringBoot跨域加SpringSecurity就失效文章插图
上图很形象的说明了 Filter 与 Interceptor 的区别 , 一个作用在 DispatcherServlet 调用前 , 一个作用在调用后 。
但实际上 , 它们本身并没有任何关系 , 是完全独立的概念 。
Filter 由 Servlet 标准定义 , 要求 Filter 需要在 Servlet 被调用之前调用 , 作用顾名思义 , 就是用来过滤请求 。 在 Spring Web 应用中 , DispatcherServlet 就是唯一的 Servlet 实现 。


推荐阅读