SpringSecurity-2.7中跨域问题
访问测试
-
起因
写这篇的起因是会了解到
SSM(@CrosOrigin)
解决跨域,但是会在加入SpringSecurity
配置后,这个跨域解决方案就失效了,而/login
这个请求上是无法添加这个注解
或者通过配置(WebMvcConfig)
去解决跨域,所以只能使用SpringSecurity
提供的.cros()
去解决跨域,但是在学习过程中,如果稍微粗心,可能会出现跨域不通的问题,而以下将会说明SpringSecurity
是如何配置跨域的 -
Postman
发起的请求不属于异步请求(区分前后端分离的JSON
)
-
使用
axios
发起异步请求,<!-- 前端: 使用 Live Server 启动访问 http://127.0.0.1:5500/index.html 后端: localhost:8080/login --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <button id="btn">发起异步请求</button> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script> let btnEl = document.querySelector('#btn'); btnEl.onclick = function () { console.log('click......................'); axios({ url: 'http://localhost:8080/login', method: 'post', data: { username: 'zhangsan', password: '123456', }, }).then((res) => { console.log(res); }); }; </script> </body> </html>
-
请求测试
SpringSecurity-配置
-
config
// 【/login】需要显示的声明出来,在前后端分离中,本文没有采用的是 ajax 向后端发送异步请求 @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { /** * 请求配置 * authorizeHttpRequests: 开启权限请求管理,针对 http 请求进行授权配置 * mvcMatchers: 匹配请求 * - permitAll: 代表放行该资源,该资源位公共资源,无需认证和授权可以直接访问 * - anyRequest().authenticated(): 代表所有请求,必须认证之后才能访问 * - formLogin: 代表开启表单认证 * <strong>放行资源必须放在认证资源之前</strong> */ http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests // 预检请求是怎么知道的:官网中有这样一段描述,如图 .antMatchers(HttpMethod.OPTIONS, "/login").permitAll() .anyRequest().authenticated() ); /** * 跨域配置 */ http.cors().configurationSource(corsConfigurationSource()); // WHITELIST 自定义的放行资源数组, /login不能出现在里面 @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring().antMatchers(WHITELIST); } } // 此处关于下方的描述可以不更改,依然使用此配置 @Bean CorsConfigurationSource corsConfigurationSource() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 新建一个跨域配置源 // 你只要点击 .cors().configurationSource( <- 点击进入这个方法,查看出这个参数,就明白为什么给了 CorsConfiguration,) CorsConfiguration configuration = new CorsConfiguration(); // 新建一个跨域配置 configuration.setAllowCredentials(true); // 【这个凭证问题,后续会给出详细解释,在 axios 的配置中默认是false,【axios 中 `withCredentials` 表示跨域请求时是否需要使用凭证】浏览器是否应当发送凭证信息,如cookie。 configuration.setAllowedMethods(Arrays.asList("*")); // 允许的请求方法,*表示允许所有方法 configuration.setAllowedHeaders(Arrays.asList("*")); // 允许的请求头,*表示允许所有头 configuration.setMaxAge(Duration.ofHours(1)); // 预检请求的有效期,有效期内不必再次发送,默认是1800秒。 configuration.setAllowedOriginPatterns(Arrays.asList("*"));// 允许的请求源 source.registerCorsConfiguration("/**", configuration); // 注册跨域配置 return source; }
-
以上配置其实可以算正确,但是有合规
在调试后发现,只需要将
/login
加入(.antMatchers("/login").permitAll()
),在所看到的视频中的关于SpringSecurity
的跨域就生效了,也可以不将预检
配置出来