SpringBoot(十五)单个以及多个跨域的配置方法
同源策略是浏览器的一个安全限制,要求域名、协议、端口相同,如果不同则没办法进行数据交互。
而跨域配置,则是为了解除这方面的限制。
前后端分离的情况下,因为需要分开部署,后台开发基本都需要进行跨域配置了。
(当然,这也可以在 nginx 上处理,这里就不展开讨论了)
spring 提供的跨域拦截器是 CorsFilter,与 CorsFilter 强关联的类是 UrlBasedCorsConfigurationSource。
跨域配置实体类
参数介绍可以看代码注释
* 跨域配置一览:
* <p>
* Access-Control-Allow-Origin: 允许访问的域名
* Access-Control-Allow-Methods: 允许访问的请求方式
* Access-Control-Allow-Headers: 允许使用的Header
* Access-Control-Allow-Credentials: 是否允许用户发送、处理Cookie
* Access-Control-Max-Age: 预检有效期,单位为秒。有效期内,不需要重复发送预检请求
* Access-Control-Expose-Headers: Header白名单,不设置的话,客户端读不到header的内容
*
* @author Mr.css
* @date 2022-03-09 16:55
*/
public class CrossDomain implements Serializable {
private static final long serialVersionUID = -3682297338044962128L;
/**
* 路径,Controller提供的接口
*/
@Length(max = 64)
@Schema(description = "路径")
private String antPath;
/**
* 允许访问的IP
*/
@Length(max = 64)
@Schema(description = "允许访问的IP")
private String allowedOrigin;
/**
* 开放请求头
*/
@Length(max = 64)
@Schema(description = "允许的请求头")
private String allowedHeader;
/**
* 开放请求方式
*/
@Length(max = 32)
@Schema(description = "允许的请求方式")
private String allowedMethod;
/**
* 白名单Header
*/
@Length(max = 64)
@Schema(description = "白名单Header")
private String exposedHeader;
/**
* 预检请求有效期
*/
@Schema(description = "预检请求有效期")
private Integer maxAge;
/**
* 允许携带凭证
*/
@Schema(description = "允许携带凭证")
private Boolean allowCredentials; // 省略getter/setter
}
Yml配置
YML配置方式,与实体类字段对应
boot-cross-domain:
config:
allowed-origin: 'http://localhost:8080'
ant-path: '/**'
allowed-header: '*'
allowed-method: '*'
allow-credentials: true
默认配置方式(单个跨域)
如果客户端不多,默认的配置就已经很好用了。
import cn.seaboot.common.core.CommonUtils;
import cn.seaboot.common.lang.Warning;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; /**
* 跨域配置
*
* @author Mr.css
* @date 2020-07-08 09:04
**/
@Configuration
@ConfigurationProperties(prefix = "boot-cross-domain")
public class CrossDomainStarter {
private Logger logger = LoggerFactory.getLogger(CrossDomainStarter.class); private CrossDomain config; public CrossDomain getConfig() {
return config;
} public void setConfig(CrossDomain config) {
this.config = config;
} @Bean
@SuppressWarnings(Warning.UNCHECKED)
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
logger.info("【Configuration】Cross domain setting: start...");
CorsConfiguration corsConfiguration = new CorsConfiguration();
String origin = config.getAllowedOrigin();
if (origin.endsWith("/") || origin.endsWith("\\")) {
origin = origin.substring(0, origin.length() - 2);
}
corsConfiguration.addAllowedOrigin(origin); //AllowedHeader
String allowHeader = config.getAllowedHeader();
if (CommonUtils.isNotEmpty(allowHeader)) {
for (String header : allowHeader.split(",")) {
corsConfiguration.addAllowedHeader(header);
}
} //AllowedMethod
String allowedMethod = config.getAllowedMethod();
if (CommonUtils.isNotEmpty(allowedMethod)) {
for (String method : allowedMethod.split(",")) {
corsConfiguration.addAllowedMethod(method);
}
}//AllowedHeader
String exposedHeader = config.getExposedHeader();
if (CommonUtils.isNotEmpty(exposedHeader)) {
for (String header : exposedHeader.split(",")) {
corsConfiguration.addExposedHeader(header);
}
} //MaxAge
if (config.getMaxAge() != null) {
corsConfiguration.setMaxAge(config.getMaxAge().longValue());
} //AllowCredentials
if (config.getAllowCredentials() != null) {
corsConfiguration.setAllowCredentials(config.getAllowCredentials());
}
logger.info("Cross domain using config: {}", config);
source.registerCorsConfiguration(config.getAntPath(), corsConfiguration);
logger.info("【Configuration】Cross domain setting: finish");
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new CorsFilter(source));
filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return filterRegistrationBean;
}
}
配置多个跨域
* Access-Control-Allow-Origin: 允许访问的域名
* Access-Control-Allow-Methods: 允许访问的请求方式
* Access-Control-Allow-Headers: 允许使用的Header
* Access-Control-Allow-Credentials: 是否允许用户发送、处理Cookie
这些参数本身就可以配置多个,用逗号分隔即可。
增加更多的跨域配置
逗号拼接的方式,决定了功能上限,如果有很多个客户端,配置起来就会很乱,比如说,我有10个客户端要配置怎么办?
这种场景下,通常会选择直接使用通配符 *,放开跨域拦截,通过业务控制,或者通过鉴权系统控制。
虽说如此,强行实现一波,应当如何?
直接看源码,上面我们用到了 UrlBasedCorsConfigurationSource,
UrlBasedCorsConfigurationSource 的父类是 CorsConfigurationSource,
这个类,相当于Dao,参数是 request,根据 request 的内容查找对应的跨域配置。
我们可以自己实现一个 CorsConfigurationSource。
代码贴出来显得文章篇幅太大,而且代码功能单一,就是配置查询,这次就简单地说明一下,下面提供了伪代码作为参考。
@Override
@Nullable
public CorsConfiguration getCorsConfiguration(@NotNull HttpServletRequest request) {
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
// 获取客户端域名
String origin = request.getHeader(HttpHeaders.ORIGIN);
// TODO: 根据客户端的域名,查找CorsConfiguration配置
return null;
}
SpringBoot(十五)单个以及多个跨域的配置方法的更多相关文章
- springboot(十八):CORS方式实现跨域
资料 https://www.cnblogs.com/toutou/p/9843588.html
- SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑
前言 最近在做项目的时候,基于前后端分离的权限管理系统,后台使用 Spring Security 作为权限控制管理, 然后在前端接口访问时候涉及到跨域,但我怎么配置跨域也没有生效,这里有一个坑,在使用 ...
- vue+springboot前后端分离实现单点登录跨域问题处理
最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登 ...
- Springboot实现filter拦截token验证和跨域
背景 web验证授权合法的一般分为下面几种 使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API接口授权验证时,token是自定义的方式实现起来不需 ...
- Web API(五):Web API跨域问题
一.什么是跨域问题 跨域:指的是浏览器不能执行其他网站的脚本.是由浏览器的同源策略造成的,是浏览器施加的安全限制.(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器 ...
- 两种解决springboot 跨域问题的方法示例
两种解决springboot 跨域问题的方法示例,哪种方法看情况而定,自己选择.社会Boolean哥,人狠话不多,直接上代码. 第一种实现方式: 此种方式做全局配置,用起来更方便,但是无法 ...
- 浅谈配置chrome浏览器允许跨域操作的方法
浅谈配置chrome浏览器允许跨域操作的方法 一:(Lying人生感悟.可忽略) 最近有一天,对着镜子,发现满脸疲惫.脸色蜡黄.头发蓬松.眼神空洞,于是痛诉着说生活的不如意,工作没激情,工资不高,一个 ...
- Nginx反向代理、CORS、JSONP等跨域请求解决方法总结
由于 Javascript 同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制.即会出现跨域请求禁止. 通俗一点说就是如果存在协议.域名.端口或者子域名不同服务端,或一者为IP地址,一者为 ...
- spring mvc \ spring boot 允许跨域请求 配置类
用@Component 注释下,随便放个地方就可以了 package com.chinaws.wsarchivesserver.core.config; import org.springframew ...
- Web Api跨域访问配置及调用示例
1.Web Api跨域访问配置. 在Web.config中的system.webServer内添加以下代码: <httpProtocol> <customHeaders> &l ...
随机推荐
- PostgreSQL数据库所有的等待事件
Wait Event Type Wait Event Name Description LWLock ShmemIndexLock Waiting to find or allocate space ...
- Postgresql动态共享内存类型
一.简介 linux为多个进程通信提供了不同的IPC机制,如:System V , POSIX 和 MMAP,所以Postgresql共享内存管理也支持以上类型. 在Postgresql中可以使用dy ...
- 开发者进阶必备的9个Tips & Tricks!
优秀的开发人员市场前景是十分广阔的,但想找到一份理想的工作,仅有代码知识是不够的.优秀的工程师应该是一个终身学习者.问题的创造性解决者,着迷于整个软件世界.要成为一名优秀的开发者,应该具备哪些品质并做 ...
- rlwrap解决opengauss,pg,oracle上下左右及回退乱码
安装下rlwrap,最新版本是0.43下载地址 https://fossies.org/linux/privat/rlwrap-0.43.tar.gz/```安装rlwraptar -zxvf rlw ...
- codeforce B. Creating the Contest
http://codeforces.com/contest/1029/problem/B 水题真快乐= = 1 public class Main { 2 public static void mai ...
- linux执行sh脚本报错:$’\r’: 未找到命令的解决
原因: 命令直接从windows 复制过来导致的 解决:我是unbutu系统 安装dos2unix apt-get install dos2unix 执行dos2unix命令转换文件格式 dos2un ...
- 硬件IIC主从机中断代码注释解析
目录 硬件IIC的主从中断在582的最新EVT中已支持. 对于IIC从机中断,例程中已封装好中断处理过程,用户调用app_i2c时,初始化中需要配置回调函数. 初始化的配置如下. struct i2c ...
- Python爬取三国演义章节标题和内容(bs4爬取,解决中文乱码)
import os.path import requests from bs4 import BeautifulSoup if __name__ == '__main__': if not os.pa ...
- ESXI虚拟机 硬盘扩容/目录(添加新硬盘)
背景: 线上服务器,磁盘Linux的虚拟机根分区已经使用90%,触发了磁盘告警,再一顿操作删除后,勉勉强强回到了82%,现在需要对根目录进行扩容. 进入到EXSI管理平台,看到原来的sda磁盘只有30 ...
- Codeforces Round #827 (Div. 4) 复盘+题解
原比赛链接 复盘: ABC签到,手速太慢了. D捣鼓了好久才想起来从更小的值域出发去做. E简单二分答案. 然后就time out了.D题搞错方向浪费太久时间了. F思维题,考虑到初值.字符集,然后是 ...