springboot版本升级,及解决springsecurity漏洞问题

背景:

项目中要解决 Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978) 漏洞问题,并且需要将项目的版本整体升级到boot版本2.1.7,升级改造过程非常的痛苦,一方面对整个框架的代码不是很熟悉,另外对解决漏洞问题相对较少。

需求:

 解决Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978) 漏洞,升级boot版本2.1.7

改造前:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.gisquest.realestate</groupId>
	<artifactId>gisqrealestate-unityplatform-core</artifactId>
	<version>2.2.1.RELEASE</version>
	<modules>
		<module>unityplatform-security</module>
        <module>unityplatform-microauth</module>
        <module>unityplatform-apigateway</module>
        <module>unityplatform-servicediscovery</module>
		<module>unityplatform-microappadmin</module>
        <module>unityplatform-apigateway-core</module>
        <module>unityplatform-apigateway-app</module>
		<module>unityplatform-microauth-app</module>
		<module>unityplatform-core-comm</module>
	</modules>
	<packaging>pom</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring-boot-admin.version>1.5.6</spring-boot-admin.version>
		<jjwt.version>0.7.0</jjwt.version>
		<commons-lang3.version>3.3.2</commons-lang3.version>
		<swagger2.version>2.7.0</swagger2.version>
		<apollo-client.version>1.0.0</apollo-client.version>
		<jackson.version>2.10.2</jackson.version>

		<!--micro version-->
		<micro-apigateway.version>2.2.1.RELEASE</micro-apigateway.version>
		<micro-auth.version>2.2.1.RELEASE</micro-auth.version>
        <micro-comm.version>2.2.1.RELEASE</micro-comm.version>

		<micro-apigateway.img.version>2.2.RELEASE</micro-apigateway.img.version>
		<micro-auth.img.version>2.2.RELEASE</micro-auth.img.version>
		<micro.img.version>2.2.RELEASE</micro.img.version>

		<com.hanweb.SecurityUtil.version>1.0</com.hanweb.SecurityUtil.version>

		<!--XStream -->
		<xstream.version>1.4.20</xstream.version>

		<spring.version>5.3.20</spring.version>
		<spring-security.version>5.5.8</spring-security.version>
	</properties>
	<dependencyManagement>
		<dependencies>

            <!--micro begin-->
			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-security-core</artifactId>
				<version>${micro-auth.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityPlatform-security-app</artifactId>
				<version>${micro-auth.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-core-comm</artifactId>
				<version>${micro-comm.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-microauth</artifactId>
				<version>${micro-auth.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-apigateway-core</artifactId>
				<version>${micro-apigateway.version}</version>
			</dependency>
			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-apigateway</artifactId>
				<version>${micro-apigateway.version}</version>
			</dependency>


			<!--micro end-->

			<dependency>
				<groupId>io.spring.platform</groupId>
				<artifactId>platform-bom</artifactId>
				<version>Brussels-SR7</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Edgware.SR2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
           #### 省略##########################
		</dependencies>
	</dependencyManagement>


	<build>
		<plugins>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>

		</plugins>
	</build>

	 
</project>

漏洞解决方案

gisqrealestate-unityplatform-core 项目下 解决Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978) 漏洞,升级boot版本2.1.7(和快速构建保持一致),注意下升级之后一些配置文件(例如redis,文件限制大小等) 和 代码 不兼容问题

漏洞影响版本

5.5.0 <= Spring Security < 5.5.7

5.6.0 <= Spring Security < 5.6.4

版本改造问题:

改造前 版本 

<spring-cloud.version>Edgware.SR2</spring-cloud.version> 
<spring-boot.version>1.5.10.RELEASE </spring-boot.version>
升级到2.x版本
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
<spring-boot.version>2.1.7.RELEASE</spring-boot.version>

问题一:项目改造前是自定义的springboot依赖,现要求去掉原先的自定义封装依赖

刚开始我是把原先自定义的springboot依赖的父依赖直接移到最外层,大概过程如下,导致出现一堆问题。

坑一:类不存在,或包不存在

但是明明可以用鼠标点击进去,此类问题经常是idea,什么缓存,或者是pom依赖下载不全导致,然后就陷入了这个误区,一直以为是idea的问题,然后idea缓存清理了很多次还是无法解决。 

然后分支代码提交后,同事检出也是同样的问题,项目还是无法启动,保错也是提示类不存在等。

此时我就怀疑可能不是idea的问题了。

后面就换了一种方式

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.5.10.RELEASE</version>
   <relativePath />
</parent>

改成

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-dependencies</artifactId>
   <version>${spring-boot.version}</version>
   <type>pom</type>
   <scope>import</scope>
</dependency>

 妈的改成这样后终于正常了,不在提示类不存在,包不存在等问题了。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<groupId>com.gisquest.realestate</groupId>
	<artifactId>gisqrealestate-unityplatform-core</artifactId>
	<version>2.2.1.RELEASE</version>
	<modelVersion>4.0.0</modelVersion>
	<packaging>pom</packaging>
	<modules>
		<module>unityplatform-security</module>
        <module>unityplatform-microauth</module>
        <module>unityplatform-apigateway</module>
        <module>unityplatform-servicediscovery</module>
		<module>unityplatform-microappadmin</module>
        <module>unityplatform-apigateway-core</module>
        <module>unityplatform-apigateway-app</module>
		<module>unityplatform-microauth-app</module>
		<module>unityplatform-core-comm</module>
	</modules>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring-boot-admin.version>1.5.6</spring-boot-admin.version>
		<jjwt.version>0.7.0</jjwt.version>
		<commons-lang3.version>3.3.2</commons-lang3.version>
		<swagger2.version>2.7.0</swagger2.version>
		<apollo-client.version>1.0.0</apollo-client.version>
		<jackson.version>2.10.2</jackson.version>
		<!--micro version-->
		<micro-apigateway.version>2.2.1.RELEASE</micro-apigateway.version>
		<micro-auth.version>2.2.1.RELEASE</micro-auth.version>
        <micro-comm.version>2.2.1.RELEASE</micro-comm.version>
		<micro-apigateway.img.version>2.2.RELEASE</micro-apigateway.img.version>
		<micro-auth.img.version>2.2.RELEASE</micro-auth.img.version>
		<micro.img.version>2.2.RELEASE</micro.img.version>
		<com.hanweb.SecurityUtil.version>1.0</com.hanweb.SecurityUtil.version>
		<!--XStream -->
		<xstream.version>1.4.19</xstream.version>
		<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
		<spring-boot.version>2.1.7.RELEASE</spring-boot.version>
		<eureka.version>2.1.0.RELEASE</eureka.version>
		<openfeign.version>2.0.0.RELEASE</openfeign.version>
		<zuul.version>2.1.2.RELEASE</zuul.version>
		<commons-lang.version>2.6</commons-lang.version>
		<commons-collections.version>3.2.2</commons-collections.version>
		<commons-beanutils.version>1.9.3</commons-beanutils.version>
	</properties>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>${spring-boot.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
            <!--micro begin-->
			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-security-core</artifactId>
				<version>${micro-auth.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityPlatform-security-app</artifactId>
				<version>${micro-auth.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-core-comm</artifactId>
				<version>${micro-comm.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-microauth</artifactId>
				<version>${micro-auth.version}</version>
			</dependency>

			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-apigateway-core</artifactId>
				<version>${micro-apigateway.version}</version>
			</dependency>
			<dependency>
				<groupId>com.gisquest.realestate</groupId>
				<artifactId>unityplatform-apigateway</artifactId>
				<version>${micro-apigateway.version}</version>
			</dependency>


			<!--micro end-->

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>


			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
				<version>${eureka.version}</version>
			</dependency>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-openfeign</artifactId>
				<version>${openfeign.version}</version>
			</dependency>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
				<version>${zuul.version}</version>
			</dependency>
	 
</project>

坑二:idea中maven设置,最好调整成maven运行

否则会出现稀奇古怪的问题,比如上面的之前用parent依赖方式我本地可以跑(奇了怪),但是同事拉下拉却跑不了,切换成eclipse也同样项目跑不起来。

经过一番折腾代码是跑起来了总算不提示类不存等问题。

代码兼容问题

org.springframework.data.redis.serializer.SerializationException: Cannot deserialize

org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.security.core.authority.SimpleGrantedAuthority; local class incompatible: stream classdesc serialVersionUID = 420, local class serialVersionUID = 510
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:84) ~[spring-data-redis-2.1.10.RELEASE.jar!/:2.1.10.RELEASE]

问题二:alibaba.fastjson.JSONObject cannot be cast to xx

java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.gisquest.realestate.security.validate.code.ValidateCode


    @Override
    public ValidateCode get(ServletWebRequest request, ValidateCodeType validateCodeType) {
        Object object = redisTemplate.opsForValue().get(buildKey(request, validateCodeType));
        if (object == null) {
            return null;
        }
   
        return (ValidateCode)object ;
    }

改造后



    @Override
    public ValidateCode get(ServletWebRequest request, ValidateCodeType validateCodeType) {
        Object object = redisTemplate.opsForValue().get(buildKey(request, validateCodeType));
        if (object == null) {
            return null;
        }
        String josn =JSON.toJSONString(object);
        return JSONObject.parseObject(josn,ValidateCode.class);
    }

问题解决!!!!

问题三:   升级后通过feign调用认证服务接口/oauth/check_token接口提示如下 Illegal hexadecimal character - at index 8
 

org.apache.commons.codec.DecoderException: Illegal hexadecimal character - at index 8
    at org.apache.commons.codec.binary.Hex.toDigit(Hex.java:286)
    at org.apache.commons.codec.binary.Hex.decodeHex(Hex.java:106)
    at com.gisquest.realestate.utils.Encodes.decodeHex(Encodes.java:41)

原因版本问题

改造前spring-security-core-4.2.4.RELEASE

在AbstractUserDetailsAuthenticationProvider在实现类中additionalAuthenticationChecks方法逻辑如下

	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
		Object salt = null;

		if (this.saltSource != null) {
			salt = this.saltSource.getSalt(userDetails);
		}

		if (authentication.getCredentials() == null) {
			logger.debug("Authentication failed: no credentials provided");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}

		String presentedPassword = authentication.getCredentials().toString();

		if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
				presentedPassword, salt)) {
			logger.debug("Authentication failed: password does not match stored value");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
	}

改造后

spring-security-core-5.1.6.RELEASE版本中AbstractUserDetailsAuthenticationProvider在实现类中改方法additionalAuthenticationChecks

   protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            this.logger.debug("Authentication failed: no credentials provided");
            throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        } else {
            String presentedPassword = authentication.getCredentials().toString();
            if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
                this.logger.debug("Authentication failed: password does not match stored value");
                throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
            }
        }
    }

   逻辑变化了

使用了自定义的密码加密类

 密码加密方式发现不一样了,因此按照原先代码逻辑获取到的前后密码其实是一样的,但是升级后GisqPasswordEncoder起了作用,因此在比较时应该时加密后的匹配

因此改成这样

问题四:feign调用token校验接口,在项目中未搜索到,

后来打断点才发现竟然后spring-security-oaruth2包内部类CheckTokenEndpoint中的接口,无语,我还以为是自己定义的呢找了半天未找打!!!!!

jar包依赖冲突问题:

方式一:选择依赖的模块,鼠标右键,选择show dependency

,如果有冲突会出现报红!!!

方式二:安装一个maven-helper插件

如果有冲突会自动显示,然后去排处即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/595841.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于视频号小店,常见问题解答,开店做店各方面详解

大家好&#xff0c;我是电商笨笨熊 视频号小店作为今年风口&#xff0c;一个新推出的项目&#xff0c;凭借着自身流量加用户群体的优势吸引了不少的电商玩家。 但对于很多玩家来说&#xff0c;视频号小店完全是一个新的项目、新的领域&#xff0c;因此也会存在很多的疑问&…

后缀字串排序

直接sort: #include <iostream> #include <cstring> #include <algorithm> #include <vector>using namespace std;int main() {string str;cin >> str;int len str.size();vector<string> strings;for(int i 0; i < len; i){strin…

云原生专栏丨基于K8s集群网络策略的应用访问控制技术

在当今云计算时代&#xff0c;Kubernetes已经成为容器编排的事实标准&#xff0c;它为容器化应用提供了强大的自动化部署、扩展和管理能力。在Kubernetes集群中&#xff0c;网络策略(Network Policy)作为对Pod间通信进行控制的关键功能&#xff0c;对保障应用安全和隔离性起到了…

[报错解决]SpringBoot子项目打jar包启动报 XXX--1.0-SNAPSHOT.jar中没有主清单属性

目录 报错信息解决原因原因分析解决方案 报错信息 解决 原因 在使用SpringBoot架构搭建父子工程时&#xff0c;使用IDEA可以正常启动&#xff0c;对子项目打成jar包后使用jar方式启动时&#xff0c;会报错xx.jar中没有主清单属性。 原因分析 原因主要是在使用jar方式启动时…

使用nvm切换nodejs版本

查看可以安装的版本&#xff1a; 使用nvm list显示已安装的nodejs版本&#xff1a; 选择一个版本下载&#xff1a; 切换对应的版本&#xff1a;

3D+仿真分析:高效实现海底石油管道系统设计

Bentley AutoPIPE 助力节省寻找更佳管道路线所需的时间和成本 评估管道完整性以提高石油产量 从墨西哥湾浅水区开采石油通常需要铺设新的海底管道&#xff0c;从而在高压和高温条件下高效、安全地输送原油。 Grupo EspecializadoenObras Marinas (GEOMSA) 是墨西哥湾管道—土体…

MaxKB宝塔Docker安装并配置域名访问

准备 Linux系统 bt面板 默认环境LNMP随便装 服务器环境配置最好是4G&#xff0c; 占用硬盘存储大概1G 对于一些海外AI产品的对接需要使用香港或者海外的服务器 安装 在宝塔面板中打开SSH或者你本地使用SSH工具去链接服务器 运行docker命令 前提是放开服务器的8080端口 doc…

顶管机种类多样 国内产量不断增长

顶管机种类多样 国内产量不断增长 顶管机是一种用于非开挖管道铺设的机械设备&#xff0c;能够通过非开挖施工技术降低对地面活动的影响&#xff0c;具有工作效率高、安全性好、受地质条件限制小、环保性强等优点&#xff0c;在隧道修建、城市管网建设、地下管线敷设等场景中发…

html5动漫风二次元网站博客引导页模板

html5动漫风二次元网站博客引导页模板 效果图部分源码领取源码下期更新预报 效果图 部分源码 <!DOCTYPE html> <!--孤独 --> <html xmlns"http://www.w3.org/1999/xhtml" lang"en"><head><meta charset"utf-8" /&g…

v-for中的key是什么作用

在使用v-for进行列表渲染时&#xff0c;我们通常会给元素或者组件绑定一个key属性。 这个key属性有什么作用呢?我们先来看一下官方的解释&#xff1a; key属性主要用在Vue的虚拟DOM算法&#xff0c;在新Inodes对比时辨识VNodes&#xff1b; 如果不使用key&#xff0c;Vue会使用…

快速了解Oracle 数据库 23ai

Oracle Database 23ai 于2024年5月2日正式发布。快速了解可以看官网主页和官方博客。 官网主页 23ai的3个要点&#xff0c;核心都是数据&#xff1a; 数据的人工智能 主要指数据库内置机器学习和AI向量搜索。这实际是Oracle融合数据库策略的延续&#xff0c;避免了复杂的数据…

Python+Selenium 实现自动化测试

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 安装selenium 打开命令控制符输入&#xff1a;pip install -U …

软件测试必问的33个面试题

1.你为什么选择软件测试行业 因为之前有了解软件测试这个行业&#xff0c;觉得他的发展前景很好。 2.根据你以前的工作经验描述一下软件开发、测试过程&#xff0c;由那些角色负责&#xff0c;你做什么 要有架构师、开发经理、测试经理、程序员、测试员。我在里面主要是负责所…

鸿蒙组件样式复用简介

鸿蒙组件样式复用简介 使用Style进行复用在Component内部复用在Component外部复用使用Extend复用指定类型组件Extend支持参数传递 使用Style进行复用 在页面开发过程中&#xff0c;会遇到多个组件都在使用相同的样式&#xff0c;这时候就要考虑是不是可以将相同的样式的进行复…

【Linux】操作系统

上一篇博客我们从硬件的角度谈了计算机&#xff0c;我们说到了计算机的效率跟操作系统写的好不好有着直接的关系&#xff0c;那么这篇博客我们从软件的角度&#xff0c;就来谈一谈究竟什么是操作系统&#xff0c;为什么要有操作系统&#xff1f; 首先我们来大体的认识一下操作…

微信小程序原生代码实现小鱼早晚安打卡小程序

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 小鱼早晚安打卡小程序&#xff1a;开启健康生活&#xff0c;共享正能量 在这个快节奏的时代&#xff0c;我们常常被各种琐事和压力所困扰&#xff0c;以至于忽略了对健康生活方式的追求。然…

QLora 里的4-bit NormalFloat Quantization中的分位数量化

目录 正态分布的分位数函数详解 1. 正态分布简介 2. 分位数函数定义 3. 正态分布的分位数函数计算 4-bit NormalFloat Quantization 4-bit NormalFloat Quantization详解 1. 4-bit NormalFloat Quantization的定义和应用 2. 4-bit NormalFloat Quantization的工作原理 …

2024.5.6

Widget::Widget(QWidget *parent): QWidget(parent) {//窗口相关设置this->setFixedSize(540,720);//背景颜色this->setStyleSheet("background-color:white");//去掉头部this->setWindowFlag(Qt::FramelessWindowHint);//标签相关设置QLabel *lab1 new QL…

screen

sLinux&#xff1a;screen命令——命令行的窗口操作_screen命令关闭窗口-CSDN博客文章浏览阅读4.2k次。功能&#xff1a;管理命令行终端切换的软件&#xff0c;常用于远程连接Linux过程中&#xff0c;同时使用多个命令行窗口。在窗口运行中的程序&#xff0c;记住窗口名字前面的…

【学习AI-相关路程-工具使用-自我学习-cudavisco-开发工具尝试-基础样例 (2)】

【学习AI-相关路程-工具使用-自我学习-cuda&visco-开发工具尝试-基础样例 &#xff08;2&#xff09;】 1、前言2、环境说明3、总结说明4、工具安装0、验证cuda1、软件下载2、插件安装 5、软件设置与编程练习1、创建目录2、编译软件进入目录&创建两个文件3、编写配置文…
最新文章