一、CORS 跨域
1、cors
- CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
- 它允许浏览器向跨源服务器,发出XMLHttpRequest(ajax)请求,从而克服了AJAX只能
同源使用的限制
。
2、同源策略
同源策略
[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。 同源策略是浏览器安全的基石。
3、源
源
[origin]就是协议、域名和端口号。例如:http://www.baidu.com:80这个URL。
4、同源
- 若地址里面的
协议、域名和端口号均相同
则属于同源。(协议 http/https) 域名 www.com/aaa.com 端口号: 80/ 8081 只要这三个是相同的那么就是同源;列如:http://127.0.0.1:8080 和 http://localhost:8080 就是非同源
# 同源举例
- 例如判断下面的URL是否与 http://www.a.com/test/index.html 同源http://www.a.com/dir/page.html --------->同源http://www.child.a.com/test/index.html ->不同源,域名不相同https://www.a.com/test/index.html ------>不同源,协议不相同http://www.a.com:8080/test/index.html -->不同源,端口号不相同
5、哪些操作不受同源限制
页面中的链接,重定向以及表单提交是不会受到同源策略限制的;
跨域资源的引入是可以的。如嵌入到页面中的
<script src="..."></script>
,<img>
,<link>
,<iframe>
等。
6、哪些操作受同源限制
- 在浏览器中发起一个AJAX请求,会受到同源策略限制。
出现错误:Access-Control-Allow-Origin
7、同源限制案例演示
利用springboot 后台启动一个程序,端口为9008,我们访问的时候 通过 http://127.0.0.1:9008/demo 跳转到 demo.html页面,在html的页面我们放一个发送ajax 的按钮,地址为 http://localhost:9008/demo/hello 两个域名不同,这个时候就会出现跨域错误了
1、controller 代码
@Controller
@RequestMapping("/demo")
public class DemoController {private final Logger logger = LoggerFactory.getLogger(this.getClass());@RequestMapping()public String index(Model model) {model.addAttribute("msg", "hello springboot cors ");return "demo";}@GetMapping("/hello")public ResponseEntity<String> hello(Model model) {return new ResponseEntity<>("hello springboot cors ajax ", HttpStatus.OK);}}
2、html 代码演示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>Title</title></head><body><!--th:text 为 Thymeleaf 属性,用于在展示文本--><h1 th:text="迎您来到Thymeleaf">测试跨域静态页面</h1><h2><span th:text="${msg }"/> </h2><button type="button" value="点我发送ajax请求" onclick="testAjax()">点我发送ajax请求</button><h4 id="msgId"></h4></body><script>function testAjax() {// 创建对象var xhr = new XMLHttpRequest();// 处理请求xhr.onreadystatechange = function (ev) {if (xhr.status == 200 && xhr.readyState == 4) {console.log(xhr.responseText);document.getElementById("msgId").innerText = "ajax返回结果:"+xhr.responseText}}// 发送请求xhr.open("get","http://localhost:9008/demo/hello");xhr.send();}
</script>
</html>
3、效果演示
8、如何解决
- 在对应的controller 上面加上注解 @CrossOrigin,需要每一个controller 都设置
- 在配置类中使用全局的bean,只需要设置一次
1、 @CrossOrigin
@Controller
@RequestMapping("/demo")
@CrossOrigin
public class DemoController
2、全局配置一个跨域的过滤器
@Configuration
public class MvcConfig implements WebMvcConfigurer {/*** 配置 springmvc 跨域请求全局过滤器方案* @return*/@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource urlSourceConfig = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用corsConfiguration.addAllowedHeader("*"); // 2允许任何头corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)urlSourceConfig.registerCorsConfiguration("/**", corsConfiguration);//4处理所有请求的跨域配置return new CorsFilter(urlSourceConfig);}@Overridepublic void addViewControllers(ViewControllerRegistry registry) {}
}
二、Jasypt 加密
Jasypt 也即Java Simplified Encryption是Sourceforge.net上的一个开源项目。在当地时间11月23号的通告中,Jasypt 1.4的新特征包括:加密属性文件(encryptable properties files)、Spring Framework集成、加密Hibernate数据源配置、新的命令行工具、URL加密的Apache wicket集成以及升级文档。
Jasypt的设计理念是简化加密操作,使其对开发者更加友好。它采用密码学强度的加密算法,支持多种加密算法,从而平衡了性能和安全性。其中,Jasypt的核心思想之一是基于密码的加密(Password Based Encryption,PBE),通过用户提供的密码生成加密密钥,然后使用该密钥对数据进行加密和解密。此外,Jasypt还引入了盐(Salt)的概念,通过添加随机生成的盐值,提高了加密的安全性,防止相同的原始数据在不同的加密过程中产生相同的结果,有效抵御彩虹表攻击。
在Spring Boot应用中,Jasypt Spring Boot Starter是一个方便的集成工具,可以简化加密功能的配置。它支持多种加密算法,包括对称加密和非对称加密,可以根据实际需求选择合适的加密方式。通过使用Jasypt Spring Boot Starter,可以轻松地将加密功能集成到Spring Boot应用中,无需手动配置复杂的加密相关的代码和配置文件。
整合springboot
1、导入依赖
<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency>
2、配置文件
- 指定加密算法
- 指定自己的秘钥,后期可以手动通过jvm设置,不需要放到配置文件中
# 加密配置
jasypt:encryptor:algorithm: PBEWithMD5AndDES#password: 1232323sdds #使用加密秘钥property:prefix: jasEnc(suffix: )
3、测试加密结果
我们使用root 字符串进行10次加密,但是每一次的结果都不一样,但是解密后还能得到密文
加密结果:rOpdwoepdL9VPYoRikFB7A==
5ZM8/cDBQMm6w1ad5JS7Kg==
0G+cQhAq8xTHEiskyr5llw==
CiwMMkQ2J+eajGUR8iC2OA==
SHkw5L6LdxSAkG9+fBj8tw==
pbJA2iifJ28QXPS1jBSZ9g==
x0m/p36RYF9eeRwDsY0vIQ==
doqPv+koOxmW8VWD6Q0l8g==
ECkOHsy6R1xpCdQ8d7fpYA==
WLp6FGscjAuPJ83gzljBrw==
X80q2/bXYvGs7lP1bN2HKw==
OebJ2wAgkICNMK2BDZzCNQ==
解密结果:root
@SpringBootTest
class SpringbootJasyptApplicationTests {@Autowiredprivate StringEncryptor encryptor;@Testpublic void testEncry() {String username = "root";String encrypt = encryptor.encrypt(username);System.out.println("加密结果:"+encrypt);IntStream.rangeClosed(0, 10).forEach(num -> {System.out.println(encryptor.encrypt(username));});String decrypt = encryptor.decrypt(encrypt);System.out.println("解密结果:"+decrypt);}
}
4、我们如何使用
我们在配置文件中配置了加密的前缀和后缀为 jasEnc(xx 加密的字符串 ),我们在需要加密的地方使用这个方法即可;
数据库连接使用
#thymeleaf 配置 spring:thymeleaf:cache: falseprefix: classpath:/templates/suffix: .html## 数据源配置datasource:password: jasEnc(7FE+i7Z7mKV9JPmDurx7DA==)username: jasEnc(IU5mwd7eRVnX+zn0aIhIVg==)url: jdbc:mysql://${mysql.host}:3306/test_rbac?characterEncoding=UTF-8type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driver## mybatis 配置 mybatis:mapper-locations: classpath:/mybatis/mapper/com/fashion/*.xml
5、测试数据库能否正常获取到结果
[{“id”:3,“loginId”:“admin”,“nickName”:“管理员账号”,“password”:“$2a$10$5VUHUT6UJG1zrSWTbMMn5O0Hie3Qh0Q5kZ9wpDRm.VOOFNoYiOFdm”}]
6、实际生产环境如何使用
我们如果将秘钥直接配置到配置文件中,有暴露的风险,这个时候我们可以通过jvm 参数动态传进去设置,这样就可以避免参数泄露了
-
idea 设置方式
-
生产环境使用
java -jar xxx.jar -Djasypt.encryptor.password=对应的秘钥
-Djasypt.encryptor.password=对应秘钥