网站外链快速建设,页面设计设计风格,浏览器主页网址推荐,网站维护运营优化公司#x1f926;♂️这个是我在springboot中使用springSecruity写一个小demo时遇到的问题#xff0c;记录下来#x1f926;♂️ 文章目录 跨域请求springboot项目中使用springSecruity导致跨域请求CrossOrigin请求失效解决方法springboot 中的跨域方法 跨域请求
什么是跨…♂️这个是我在springboot中使用springSecruity写一个小demo时遇到的问题记录下来♂️ 文章目录 跨域请求springboot项目中使用springSecruity导致跨域请求CrossOrigin请求失效解决方法springboot 中的跨域方法 跨域请求
什么是跨域请求为啥会有跨域请求 跨域请求就是说浏览器在执行脚本文件的ajax请求时脚本文件所在的服务地址和请求的服务地址不一样。说白了就是ip、网络协议、端口都一样的时候就是同一个域否则就是跨域。这是由于Netscape提出一个著名的安全策略——同源策略造成的这是浏览器对JavaScript施加的安全限制。是防止外网的脚本恶意攻击服务器的一种措施。 俺们先来看看请求又有哪几种吧 1.简单请求 简单请求是指符合跨域请求规范中定义的一种简单请求类型。简单请求必须满足以下条件 请求方法限于 GET、POST 或 HEAD 只能使用以下几种 Content-Typeapplication/x-www-form-urlencoded、multipart/form-data、text/plain 请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器 请求中没有使用 ReadableStream 对象 请求中的任意 ReadableStream 对象均没有被启动 请求的 method 属性不是 GET、HEAD 或 POST 以外的字符串 请求的带有信函头之一。 简单请求不会触发预检请求OPTIONS 请求而是直接发送实际的请求。这样可以减少跨域请求的复杂性和延迟。 对于简单请求 CORS的策略是请求时在请求头中增加一个Origin字段服务器收到请求后根据该字段判断是否允许该请求访问。 1.如果允许则在 HTTP 头信息中添加 Access-Control-Allow-Origin 字段并返回正确的结果 2.如果不 允许则不在 HTTP 头信息中添加 Access-Control-Allow-Origin 字段 。 2.非简单请求 对于非简单请求的跨源请求浏览器会在真实请求发出前增加一次OPTION请求称为预检请求(preflight request)。预检请求将真实请求的信息包括请求方法、自定义头字段、源信息添加到 HTTP 头信息字段中询问服务器是否允许这样的操作。
例如一个DELETE请求
OPTIONS /test HTTP/1.1
Origin: http://www.examples.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: X-Custom-Header
Host: www.examples.com
与 CORS 相关的字段有
请求使用的 HTTP 方法 Access-Control-Request-Method
请求中包含的自定义头字段 Access-Control-Request-Headers 。
服务器收到请求时需要分别对 Origin、Access-Control-Request-Method、Access-Control-Request-Headers 进行验证验证通过后会在返回 HTTP头信息中添加 Access-Control-Allow-Origin: http://www.examples.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
他们的含义分别是Access-Control-Allow-Methods: 真实请求允许的方法
Access-Control-Allow-Headers: 服务器允许使用的字段
Access-Control-Allow-Credentials: 是否允许用户发送、处理 cookie
Access-Control-Max-Age: 预检请求的有效期单位为秒。有效期内不会重复发送预检请求
当预检请求通过后浏览器会发送真实请求到服务器。这就实现了跨源请求。总之跨域请求会经历的几个步骤也就这几步 1.访问另一个域的资源。 2.有可能会发起一次预检请求非简单请求或超过了 Max-Age。 3.发起实际请求。 springboot项目中使用springSecruity导致跨域请求CrossOrigin请求失效解决方法
第一步 想访问的controller类该加上CrossOrigin还加上不要删除 第二步 配置springSecruity配置类,添加跨域配置 下面代码中通过调用http.cors().and().csrf().disable()方法来启用跨域配置并禁用CSRF保护。 package com.example.sec_demo1.config;/*** ClassName Sccc* Description TODO* Author zyhh* date 2024/2/29 14:27* version: 1.0*/import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsUtils;/*** SpringSecurity配置类*/
Configuration
EnableWebSecurity
EnableGlobalMethodSecurity(prePostEnabled true, securedEnabled true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {/*** 授权** param http* throws Exception*/Overrideprotected void configure(HttpSecurity http) throws Exception {// 开启跨域访问http.cors(); //.disable();// 开启模拟请求比如API POST测试工具的测试不开启时API POST为报403错误http.csrf().disable();// iframe 跳转错误处理 Refused to display url in a frame because it set X-Frame-Options to denyhttp.headers().frameOptions().disable();// 当出现跨域的OPTIONS请求时发现被拦截加入下面设置可实现对OPTIONS请求的放行。http.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll();}
}
第三步 配置一个CorsConfigurationSource的Bean来定义跨域配置。 通过CorsConfigurationSource的Bean定义了允许的来源、方法和头部,并将其应用到所有路径上。 Configuration
public class CorsConfig {Beanpublic CorsConfigurationSource corsConfigurationSource() {CorsConfiguration configuration new CorsConfiguration();configuration.addAllowedOrigin(*);configuration.addAllowedMethod(*);configuration.addAllowedHeader(*);UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**, configuration);return source;}
}over
再补充一点哈哈
springboot 中的跨域方法 有三种 1.针对单个 API的 2.针对整个应用的 3.在一些情况下是等效的而在另一些情况下却又出现不同 针对单个API的 其实就是使用CrossOrigin。可以加类上也可以加单个方法上。 针对整个应用的 实现 WebMvcConfigurerz中的addCorsMappings 方法 /*** SpringMVC 跨域配置*/
Configuration
public class MvcConfig implements WebMvcConfigurer {Beanpublic CorsFilter corsFilter() {final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource new UrlBasedCorsConfigurationSource();final CorsConfiguration corsConfiguration new CorsConfiguration();corsConfiguration.setAllowCredentials(true); /*是否允许请求带有验证信息*/corsConfiguration.addAllowedOrigin(*);/*允许访问的客户端域名*/corsConfiguration.addAllowedHeader(*);/*允许服务端访问的客户端请求头*/corsConfiguration.addAllowedMethod(*); /*允许访问的方法名,GET POST等*/corsConfiguration.addExposedHeader(token);/*暴露哪些头部信息 不能用*因为跨域访问默认不能获取全部头部信息*/corsConfiguration.addExposedHeader(TOKEN);corsConfiguration.addExposedHeader(Authorization);urlBasedCorsConfigurationSource.registerCorsConfiguration(/**, corsConfiguration);return new CorsFilter(urlBasedCorsConfigurationSource);}
}在一些情况下是等效的而在另一些情况下却又出现不同 注入 CorsFilter 注入 CorsFilter 不止这一种方式我们还可以通过注入一个 FilterRegistrationBean 来实现这里就不给例子了。 WebFilter(/*)
public class CORSFilter implements Filter {Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException, ServletException, IOException {HttpServletRequest request (HttpServletRequest) servletRequest;HttpServletResponse resp (HttpServletResponse) servletResponse;// 告诉浏览器允许所有的域访问// 注意 * 不能满足带有cookie的访问,Origin 必须是全匹配// resp.addHeader(Access-Control-Allow-Origin, *);// 解决办法通过获取Origin请求头来动态设置String origin request.getHeader(Origin);if (StringUtils.hasText(origin)) {resp.addHeader(Access-Control-Allow-Origin, origin);}// 允许带有cookie访问resp.addHeader(Access-Control-Allow-Credentials, true);// 告诉浏览器允许跨域访问的方法resp.addHeader(Access-Control-Allow-Methods, *);// 告诉浏览器允许带有Content-Type,header1,header2头的请求访问// resp.addHeader(Access-Control-Allow-Headers, Content-Type,header1,header2);// 设置支持所有的自定义请求头String headers request.getHeader(Access-Control-Request-Headers);if (StringUtils.hasText(headers)) {resp.addHeader(Access-Control-Allow-Headers, headers);}// 告诉浏览器缓存OPTIONS预检请求1小时,避免非简单请求每次发送预检请求,提升性能resp.addHeader(Access-Control-Max-Age, 3600);chain.doFilter(request, resp);}
}以上是springboot才需要的配置如果是springbootspringSecruity。这些是没办法使用的。得使用 CorsConfigurationSource配置类和 继承WebSecurityConfigurerAdapter类并实现configure方法。