Spring Boot中如何解决跨越问题?
been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
--访问一个什么地址被CORS 协议阻止, 没有 在Hearder 里面发现 Access-Control-Allow-Origin 的参数的资源
原因:浏览器的同源策略(Same-Origin Policy),该策略限制了不同源之间的交互
什么是同源策略?
- 安全策略,用于保护Web浏览器中的文档对象模型(DOM)免受恶意网站的攻击;它是一种浏览器的安全机制,用于限制一个源(包括协议、域名和端口)的文档或脚本如何与其他源的资源进行交互
- 原则是:只有当两个页面具有相同的协议(HTTP或HTTPS)、主机名和端口号时,它们才被认为是同源的;如果两个页面不满足同源策略,那么它们之间的交互将受到限制
- 目的是防止恶意网站通过跨域请求或访问其他网站的敏感数据,从而保护用户的隐私和安全;例如,如果一个网站加载了一个恶意脚本,它将无法通过XMLHttpRequest或Fetch API发送跨域请求到其他网站,因为浏览器会阻止这种行为
- 可以使用CORS(跨域资源共享)机制来实现跨域访问的控制
什么是源和跨域?
源:协议、域名和端口号
URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口全部相同,则表示他们同源;否则,只要协议、域名、端口有任何一个不同就是跨域
对https://www.baidu.com/index.html进行跨越比较:
URL | 是否跨域 | 原因 |
---|---|---|
https://www.baidu.com/more/index.html | no | 三要素相同 |
https://www.baidu.com/ | yes | 域名不同 |
http://www.baidu.com/index.html | yes | 协议不同 |
https://www.baidu.com:81/index.html | yes | 端口号不同 |
解决跨域问题方法?
- 使用`@CrossOrigin`注解:可以在Controller类或具体的请求处理方法上添加`@CrossOrigin`注解来指定允许跨域访问的域名;在Spring Boot应用程序的配置类或者Web配置类中添加一个
CorsFilter
bean@Configuration public class WebConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); // 允许所有域名进行跨域访问,可以根据需求进行配置 config.addAllowedMethod("*"); // 允许所有HTTP方法进行跨域访问 config.addAllowedHeader("*"); // 允许所有请求头进行跨域访问 source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
- 在Controller类或者具体的请求处理方法上添加
@CrossOrigin
注解,以允许特定的跨域请求@RestController public class MyController { @CrossOrigin(origins = "http://example.com") // 允许http://example.com进行跨域访问 @GetMapping("/api/data") public String getData() { // 处理请求并返回数据 return "Data"; } }
使用
@CrossOrigin
注解来指定允许跨域访问的域名。可以根据需要配置多个域名,或者使用通配符"*"
来允许所有域名进行跨域访问 -
使用全局配置类:可以创建一个全局配置类,继承`WebMvcConfigurerAdapter`并重写`addCorsMappings`方法,配置全局的跨域访问规则
@Configuration public class CorsConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://example.com") // 允许http://example.com进行跨域访问 .allowedMethods("*") // 允许所有HTTP方法进行跨域访问 .allowedHeaders("*"); // 允许所有请求头进行跨域访问 } }
-
使用过滤器:可以创建一个自定义的过滤器来处理跨域请求,设置相应的响应头信息
@Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setHeader("Access-Control-Allow-Origin", "http://example.com"); // 允许http://example.com进行跨域访问 httpServletResponse.setHeader("Access-Control-Allow-Methods", "*"); // 允许所有HTTP方法进行跨域访问 httpServletResponse.setHeader("Access-Control-Allow-Headers", "*"); // 允许所有请求头进行跨域访问 chain.doFilter(request, response); } }
-
使用Spring Security配置:如果你的应用程序使用了Spring Security,可以在配置类中添加相应的跨域配置@EnableWebSecurity
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors(); // 开启跨域支持 // 其他的安全配置 } }
什么是CSRF攻击?
one-click attack或者 session riding,全称是叫跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令;常用于盗取账号、转账、发送虚假消息等;攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为
CSRF(Cross-Site Request Forgery)攻击是一种利用受信任用户的身份执行非预期操作的攻击方式;攻击者通过诱使用户在已登录的受信任网站上执行恶意操作,从而利用用户的身份发送未经授权的请求
CSRF攻击的过程是怎么样?
- 用户登录受信任网站A,并获取了一个有效的会话凭证(例如通过Cookie)
- 用户在不知情的情况下访问了恶意网站B
- 恶意网站B中的恶意代码会自动向受信任网站A发送一个请求,该请求会利用用户的会话凭证执行某个操作(例如修改用户信息、发起资金转账等)
- 受信任网站A接收到请求后,由于请求中包含了有效的会话凭证,会误认为是用户本人发出的请求,从而执行了恶意操作
CSRF攻击的危害在于它可以利用用户的身份执行一些非法或未授权的操作,例如篡改用户信息、发起资金转账、删除重要数据等;攻击者通常会利用社交工程、钓鱼网站、恶意广告等方式来引诱用户点击恶意链接或访问恶意网站,从而触发CSRF攻击
为了防止CSRF攻击,可以采取哪几种防御措施?
- 使用CSRF令牌:在每个表单或请求中添加一个CSRF令牌,该令牌由服务器生成并与用户会话相关联。在处理请求时,服务器会验证令牌的有效性,只有在令牌有效的情况下才执行操作
- 检查Referer头:服务器可以检查请求中的Referer头,确保请求来源于合法的域名;然而,这种方法并不完全可靠,因为有些浏览器可能会禁用或修改Referer头
- 使用SameSite Cookie属性:将Cookie的SameSite属性设置为Strict或Lax,限制Cookie只能在同源请求中发送,从而防止跨域请求中的CSRF攻击
- 避免使用GET请求进行敏感操作:将敏感操作改为使用POST、PUT、DELETE等非GET请求,因为GET请求可以通过URL链接进行CSRF攻击
采取适当的防御措施可以有效防止CSRF攻击,保护用户的安全和隐私