mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-01-04 04:45:28 +08:00
Compare commits
8 Commits
2298ee3eed
...
v3.8.3
| Author | SHA1 | Date | |
|---|---|---|---|
| bc04bd1433 | |||
| 35aba0784d | |||
| c3822ab702 | |||
| d4487356f0 | |||
| ae4363dc72 | |||
| 3e6c7651ee | |||
| c0ffd14b7a | |||
| 914875d6a1 |
BIN
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.dmp
Normal file
BIN
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.dmp
Normal file
Binary file not shown.
29702
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.sql
Normal file
29702
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.sql
Normal file
File diff suppressed because one or more lines are too long
25749
jeecg-boot/db/其他数据库脚本/jeecgboot-postgresql17.sql
Normal file
25749
jeecg-boot/db/其他数据库脚本/jeecgboot-postgresql17.sql
Normal file
File diff suppressed because one or more lines are too long
48117
jeecg-boot/db/其他数据库脚本/jeecgboot-sqlserver2017.sql
Normal file
48117
jeecg-boot/db/其他数据库脚本/jeecgboot-sqlserver2017.sql
Normal file
File diff suppressed because one or more lines are too long
@ -153,9 +153,9 @@ public class CommonUtils {
|
|||||||
*/
|
*/
|
||||||
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
|
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
|
||||||
try {
|
try {
|
||||||
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
// 文件安全校验,防止上传漏洞文件
|
||||||
SsrfFileTypeFilter.checkUploadFileType(mf);
|
SsrfFileTypeFilter.checkUploadFileType(mf, bizPath);
|
||||||
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
|
||||||
String fileName = null;
|
String fileName = null;
|
||||||
File file = new File(uploadpath + File.separator + bizPath + File.separator );
|
File file = new File(uploadpath + File.separator + bizPath + File.separator );
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
|
|||||||
@ -55,13 +55,11 @@ public class MinioUtil {
|
|||||||
*/
|
*/
|
||||||
public static String upload(MultipartFile file, String bizPath, String customBucket) throws Exception {
|
public static String upload(MultipartFile file, String bizPath, String customBucket) throws Exception {
|
||||||
String fileUrl = "";
|
String fileUrl = "";
|
||||||
//update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
|
// 业务路径过滤,防止攻击
|
||||||
bizPath = StrAttackFilter.filter(bizPath);
|
bizPath = StrAttackFilter.filter(bizPath);
|
||||||
//update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
|
|
||||||
|
|
||||||
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
// 文件安全校验,防止上传漏洞文件
|
||||||
SsrfFileTypeFilter.checkUploadFileType(file);
|
SsrfFileTypeFilter.checkUploadFileType(file, bizPath);
|
||||||
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
|
||||||
|
|
||||||
String newBucket = bucketName;
|
String newBucket = bucketName;
|
||||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package org.jeecg.common.util.filter;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -149,29 +150,38 @@ public class SsrfFileTypeFilter {
|
|||||||
public static void checkDownloadFileType(String filePath) throws IOException {
|
public static void checkDownloadFileType(String filePath) throws IOException {
|
||||||
//文件后缀
|
//文件后缀
|
||||||
String suffix = getFileTypeBySuffix(filePath);
|
String suffix = getFileTypeBySuffix(filePath);
|
||||||
log.info("suffix:{}", suffix);
|
log.debug(" 【文件下载校验】文件后缀 suffix: {}", suffix);
|
||||||
boolean isAllowExtension = FILE_TYPE_WHITE_LIST.contains(suffix.toLowerCase());
|
boolean isAllowExtension = FILE_TYPE_WHITE_LIST.contains(suffix.toLowerCase());
|
||||||
//是否允许下载的文件
|
//是否允许下载的文件
|
||||||
if (!isAllowExtension) {
|
if (!isAllowExtension) {
|
||||||
throw new IOException("下载失败,存在非法文件类型:" + suffix);
|
throw new JeecgBootException("下载失败,存在非法文件类型:" + suffix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件类型过滤
|
* 上传文件类型过滤
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
public static void checkUploadFileType(MultipartFile file) throws Exception {
|
public static void checkUploadFileType(MultipartFile file) throws Exception {
|
||||||
//获取文件真是后缀
|
checkUploadFileType(file, null);
|
||||||
String suffix = getFileType(file);
|
}
|
||||||
|
|
||||||
log.info("suffix:{}", suffix);
|
/**
|
||||||
|
* 上传文件类型过滤
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
*/
|
||||||
|
public static void checkUploadFileType(MultipartFile file, String customPath) throws Exception {
|
||||||
|
//1. 路径安全校验
|
||||||
|
validatePathSecurity(customPath);
|
||||||
|
//2. 校验文件后缀和头
|
||||||
|
String suffix = getFileType(file, customPath);
|
||||||
|
log.info("【文件上传校验】文件后缀 suffix: {},customPath:{}", suffix, customPath);
|
||||||
boolean isAllowExtension = FILE_TYPE_WHITE_LIST.contains(suffix.toLowerCase());
|
boolean isAllowExtension = FILE_TYPE_WHITE_LIST.contains(suffix.toLowerCase());
|
||||||
//是否允许下载的文件
|
//是否允许下载的文件
|
||||||
if (!isAllowExtension) {
|
if (!isAllowExtension) {
|
||||||
throw new Exception("上传失败,存在非法文件类型:" + suffix);
|
throw new JeecgBootException("上传失败,存在非法文件类型:" + suffix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +193,7 @@ public class SsrfFileTypeFilter {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static String getFileType(MultipartFile file) throws Exception {
|
private static String getFileType(MultipartFile file, String customPath) throws Exception {
|
||||||
//update-begin-author:liusq date:20230404 for: [issue/4672]方法造成的文件被占用,注释掉此方法tomcat就能自动清理掉临时文件
|
//update-begin-author:liusq date:20230404 for: [issue/4672]方法造成的文件被占用,注释掉此方法tomcat就能自动清理掉临时文件
|
||||||
String fileExtendName = null;
|
String fileExtendName = null;
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
@ -203,7 +213,7 @@ public class SsrfFileTypeFilter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info("-----获取到的指定文件类型------"+fileExtendName);
|
log.debug("-----获取到的指定文件类型------"+fileExtendName);
|
||||||
// 如果不是上述类型,则判断扩展名
|
// 如果不是上述类型,则判断扩展名
|
||||||
if (StringUtils.isBlank(fileExtendName)) {
|
if (StringUtils.isBlank(fileExtendName)) {
|
||||||
String fileName = file.getOriginalFilename();
|
String fileName = file.getOriginalFilename();
|
||||||
@ -214,7 +224,6 @@ public class SsrfFileTypeFilter {
|
|||||||
// 如果有扩展名,则返回扩展名
|
// 如果有扩展名,则返回扩展名
|
||||||
return getFileTypeBySuffix(fileName);
|
return getFileTypeBySuffix(fileName);
|
||||||
}
|
}
|
||||||
log.info("-----最終的文件类型------"+fileExtendName);
|
|
||||||
is.close();
|
is.close();
|
||||||
return fileExtendName;
|
return fileExtendName;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -249,4 +258,34 @@ public class SsrfFileTypeFilter {
|
|||||||
}
|
}
|
||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路径安全校验
|
||||||
|
*/
|
||||||
|
private static void validatePathSecurity(String customPath) throws JeecgBootException {
|
||||||
|
if (customPath == null || customPath.trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一分隔符为 /
|
||||||
|
String normalized = customPath.replace("\\", "/");
|
||||||
|
|
||||||
|
// 1. 防止路径遍历攻击
|
||||||
|
if (normalized.contains("..") || normalized.contains("~")) {
|
||||||
|
throw new JeecgBootException("上传业务路径包含非法字符!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 限制路径深度
|
||||||
|
int depth = normalized.split("/").length;
|
||||||
|
if (depth > 5) {
|
||||||
|
throw new JeecgBootException("上传业务路径深度超出限制!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 限制字符集(只允许字母、数字、下划线、横线、斜杠)
|
||||||
|
if (!normalized.matches("^[a-zA-Z0-9/_-]+$")) {
|
||||||
|
throw new JeecgBootException("上传业务路径包含非法字符!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,9 +97,8 @@ public class OssBootUtil {
|
|||||||
* @return oss 中的相对文件路径
|
* @return oss 中的相对文件路径
|
||||||
*/
|
*/
|
||||||
public static String upload(MultipartFile file, String fileDir,String customBucket) throws Exception {
|
public static String upload(MultipartFile file, String fileDir,String customBucket) throws Exception {
|
||||||
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
// 文件安全校验,防止上传漏洞文件
|
||||||
SsrfFileTypeFilter.checkUploadFileType(file);
|
SsrfFileTypeFilter.checkUploadFileType(file);
|
||||||
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
|
||||||
|
|
||||||
String filePath = null;
|
String filePath = null;
|
||||||
initOss(endPoint, accessKeyId, accessKeySecret);
|
initOss(endPoint, accessKeyId, accessKeySecret);
|
||||||
|
|||||||
@ -11,22 +11,19 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
|||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||||
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
|
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import org.springframework.http.CacheControl;
|
import org.springframework.http.CacheControl;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
@ -50,6 +47,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* @Author qinfeng
|
* @Author qinfeng
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebMvcConfiguration implements WebMvcConfigurer {
|
public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
@ -157,16 +155,17 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听应用启动完成事件,确保 PrometheusMeterRegistry 已经初始化
|
* 在Bean初始化完成后立即配置PrometheusMeterRegistry,避免在Meter注册后才配置MeterFilter
|
||||||
* for [QQYUN-12558]【监控】系统监控的头两个tab不好使,接口404
|
* for [QQYUN-12558]【监控】系统监控的头两个tab不好使,接口404
|
||||||
* @param event
|
|
||||||
* @author chenrui
|
* @author chenrui
|
||||||
* @date 2025/5/26 16:46
|
* @date 2025/5/26 16:46
|
||||||
*/
|
*/
|
||||||
@EventListener
|
@PostConstruct
|
||||||
public void onApplicationReady(ApplicationReadyEvent event) {
|
public void initPrometheusMeterRegistry() {
|
||||||
if(null != meterRegistryPostProcessor){
|
// 确保在应用启动早期就配置MeterFilter,避免警告
|
||||||
meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, "");
|
if (null != meterRegistryPostProcessor && null != prometheusMeterRegistry) {
|
||||||
|
meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, "prometheusMeterRegistry");
|
||||||
|
log.info("PrometheusMeterRegistry配置完成");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -158,7 +158,7 @@ public class ShiroConfig {
|
|||||||
filterChainDefinitionMap.put("/drag/onlDragDatasetHead/getTotalDataByCompId", "anon");
|
filterChainDefinitionMap.put("/drag/onlDragDatasetHead/getTotalDataByCompId", "anon");
|
||||||
filterChainDefinitionMap.put("/drag/mock/json/**", "anon");
|
filterChainDefinitionMap.put("/drag/mock/json/**", "anon");
|
||||||
filterChainDefinitionMap.put("/drag/onlDragDatasetHead/getDictByCodes", "anon");
|
filterChainDefinitionMap.put("/drag/onlDragDatasetHead/getDictByCodes", "anon");
|
||||||
|
filterChainDefinitionMap.put("/drag/onlDragDatasetHead/queryAllById", "anon");
|
||||||
filterChainDefinitionMap.put("/jimubi/view", "anon");
|
filterChainDefinitionMap.put("/jimubi/view", "anon");
|
||||||
filterChainDefinitionMap.put("/jimubi/share/view/**", "anon");
|
filterChainDefinitionMap.put("/jimubi/share/view/**", "anon");
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
<!-- 积木报表 -->
|
<!-- 积木报表 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
|
<artifactId>jimureport-spring-boot3-starter</artifactId>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>com.github.jsqlparser</groupId>
|
<groupId>com.github.jsqlparser</groupId>
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.SymbolConstant;
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
import org.jeecg.common.constant.enums.FileTypeEnum;
|
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
|
||||||
import org.jeecg.common.util.CommonUtils;
|
import org.jeecg.common.util.CommonUtils;
|
||||||
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -22,8 +21,6 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
|
|||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,50 +65,19 @@ public class CommonController {
|
|||||||
Result<?> result = new Result<>();
|
Result<?> result = new Result<>();
|
||||||
String savePath = "";
|
String savePath = "";
|
||||||
String bizPath = request.getParameter("biz");
|
String bizPath = request.getParameter("biz");
|
||||||
|
|
||||||
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
|
||||||
if (oConvertUtils.isNotEmpty(bizPath)) {
|
|
||||||
if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
|
|
||||||
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||||
// 获取上传文件对象
|
|
||||||
MultipartFile file = multipartRequest.getFile("file");
|
MultipartFile file = multipartRequest.getFile("file");
|
||||||
if(oConvertUtils.isEmpty(bizPath)){
|
|
||||||
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
// 文件安全校验,防止上传漏洞文件
|
||||||
//未指定目录,则用阿里云默认目录 upload
|
SsrfFileTypeFilter.checkUploadFileType(file, bizPath);
|
||||||
bizPath = "upload";
|
|
||||||
//result.setMessage("使用阿里云文件上传时,必须添加目录!");
|
if (oConvertUtils.isEmpty(bizPath)) {
|
||||||
//result.setSuccess(false);
|
bizPath = CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType) ? "upload" : "";
|
||||||
//return result;
|
|
||||||
}else{
|
|
||||||
bizPath = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||||
//update-begin-author:liusq date:20221102 for: 过滤上传文件类型
|
|
||||||
SsrfFileTypeFilter.checkUploadFileType(file);
|
|
||||||
//update-end-author:liusq date:20221102 for: 过滤上传文件类型
|
|
||||||
//update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
|
|
||||||
savePath = this.uploadLocal(file,bizPath);
|
savePath = this.uploadLocal(file,bizPath);
|
||||||
//update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
|
|
||||||
/** 富文本编辑器及markdown本地上传时,采用返回链接方式
|
|
||||||
//针对jeditor编辑器如何使 lcaol模式,采用 base64格式存储
|
|
||||||
String jeditor = request.getParameter("jeditor");
|
|
||||||
if(oConvertUtils.isNotEmpty(jeditor)){
|
|
||||||
result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL);
|
|
||||||
result.setSuccess(true);
|
|
||||||
return result;
|
|
||||||
}else{
|
|
||||||
savePath = this.uploadLocal(file,bizPath);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}else{
|
}else{
|
||||||
//update-begin-author:taoyan date:20200814 for:文件上传改造
|
|
||||||
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
||||||
//update-end-author:taoyan date:20200814 for:文件上传改造
|
|
||||||
}
|
}
|
||||||
if(oConvertUtils.isNotEmpty(savePath)){
|
if(oConvertUtils.isNotEmpty(savePath)){
|
||||||
result.setMessage(savePath);
|
result.setMessage(savePath);
|
||||||
|
|||||||
@ -2,9 +2,9 @@ package org.jeecg.modules.system.controller;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.exception.JeecgBootException;
|
|
||||||
import org.jeecg.common.util.CommonUtils;
|
import org.jeecg.common.util.CommonUtils;
|
||||||
import org.jeecg.common.util.MinioUtil;
|
import org.jeecg.common.util.MinioUtil;
|
||||||
|
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.oss.entity.OssFile;
|
import org.jeecg.modules.oss.entity.OssFile;
|
||||||
import org.jeecg.modules.oss.service.IOssFileService;
|
import org.jeecg.modules.oss.service.IOssFileService;
|
||||||
@ -35,20 +35,18 @@ public class SysUploadController {
|
|||||||
@PostMapping(value = "/uploadMinio")
|
@PostMapping(value = "/uploadMinio")
|
||||||
public Result<?> uploadMinio(HttpServletRequest request) throws Exception {
|
public Result<?> uploadMinio(HttpServletRequest request) throws Exception {
|
||||||
Result<?> result = new Result<>();
|
Result<?> result = new Result<>();
|
||||||
|
// 获取业务路径
|
||||||
String bizPath = request.getParameter("biz");
|
String bizPath = request.getParameter("biz");
|
||||||
|
// 获取上传文件对象
|
||||||
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||||
boolean flag = oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"));
|
MultipartFile file = multipartRequest.getFile("file");
|
||||||
if (flag) {
|
|
||||||
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
// 文件安全校验,防止上传漏洞文件
|
||||||
}
|
SsrfFileTypeFilter.checkUploadFileType(file, bizPath);
|
||||||
|
|
||||||
if(oConvertUtils.isEmpty(bizPath)){
|
if(oConvertUtils.isEmpty(bizPath)){
|
||||||
bizPath = "";
|
bizPath = "";
|
||||||
}
|
}
|
||||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
|
||||||
// 获取上传文件对象
|
|
||||||
MultipartFile file = multipartRequest.getFile("file");
|
|
||||||
// 获取文件名
|
// 获取文件名
|
||||||
String orgName = file.getOriginalFilename();
|
String orgName = file.getOriginalFilename();
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import org.jeecg.common.system.api.ISysBaseAPI;
|
|||||||
import org.jeecg.common.system.vo.SysFilesModel;
|
import org.jeecg.common.system.vo.SysFilesModel;
|
||||||
import org.jeecg.common.util.CommonUtils;
|
import org.jeecg.common.util.CommonUtils;
|
||||||
import org.jeecg.common.util.RedisUtil;
|
import org.jeecg.common.util.RedisUtil;
|
||||||
|
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.system.entity.SysComment;
|
import org.jeecg.modules.system.entity.SysComment;
|
||||||
import org.jeecg.modules.system.entity.SysFormFile;
|
import org.jeecg.modules.system.entity.SysFormFile;
|
||||||
@ -119,28 +120,24 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Override
|
@Override
|
||||||
public void saveOneFileComment(HttpServletRequest request) {
|
public void saveOneFileComment(HttpServletRequest request) {
|
||||||
|
|
||||||
//update-begin-author:taoyan date:2023-6-12 for: QQYUN-4310【文件】从文件库选择文件功能未做
|
|
||||||
String existFileId = request.getParameter("fileId");
|
String existFileId = request.getParameter("fileId");
|
||||||
if(oConvertUtils.isEmpty(existFileId)){
|
if(oConvertUtils.isEmpty(existFileId)){
|
||||||
String savePath = "";
|
String savePath = "";
|
||||||
|
// 获取业务路径
|
||||||
String bizPath = request.getParameter("biz");
|
String bizPath = request.getParameter("biz");
|
||||||
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
|
||||||
if (oConvertUtils.isNotEmpty(bizPath)) {
|
|
||||||
if (bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)) {
|
|
||||||
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
|
||||||
// 获取上传文件对象
|
// 获取上传文件对象
|
||||||
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||||
MultipartFile file = multipartRequest.getFile("file");
|
MultipartFile file = multipartRequest.getFile("file");
|
||||||
|
|
||||||
|
// 文件安全校验,防止上传漏洞文件
|
||||||
|
try {
|
||||||
|
SsrfFileTypeFilter.checkUploadFileType(file, bizPath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JeecgBootException(e);
|
||||||
|
}
|
||||||
|
|
||||||
if (oConvertUtils.isEmpty(bizPath)) {
|
if (oConvertUtils.isEmpty(bizPath)) {
|
||||||
if (CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)) {
|
bizPath = CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType) ? "upload" : "";
|
||||||
//未指定目录,则用阿里云默认目录 upload
|
|
||||||
bizPath = "upload";
|
|
||||||
} else {
|
|
||||||
bizPath = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
|
if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
|
||||||
savePath = this.uploadLocal(file, bizPath);
|
savePath = this.uploadLocal(file, bizPath);
|
||||||
@ -348,10 +345,13 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String uploadLocal(MultipartFile mf, String bizPath) {
|
private String uploadLocal(MultipartFile mf, String bizPath) {
|
||||||
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
try {
|
||||||
if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) {
|
// 文件安全校验,防止上传漏洞文件
|
||||||
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
SsrfFileTypeFilter.checkUploadFileType(mf, bizPath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JeecgBootException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String ctxPath = uploadpath;
|
String ctxPath = uploadpath;
|
||||||
String fileName = null;
|
String fileName = null;
|
||||||
|
|||||||
@ -6,10 +6,10 @@ import org.jeecg.common.util.oConvertUtils;
|
|||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
@ -22,9 +22,8 @@ import java.util.Map;
|
|||||||
* 报错提醒: 未集成mongo报错,可以打开启动类上面的注释 exclude={MongoAutoConfiguration.class}
|
* 报错提醒: 未集成mongo报错,可以打开启动类上面的注释 exclude={MongoAutoConfiguration.class}
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@SpringBootApplication
|
@SpringBootApplication(exclude = MongoAutoConfiguration.class)
|
||||||
@ImportAutoConfiguration(JustAuthAutoConfiguration.class) // spring boot 3.x justauth 兼容性处理
|
@ImportAutoConfiguration(JustAuthAutoConfiguration.class) // spring boot 3.x justauth 兼容性处理
|
||||||
//@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
|
|
||||||
public class JeecgSystemApplication extends SpringBootServletInitializer {
|
public class JeecgSystemApplication extends SpringBootServletInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
<!-- 积木报表-->
|
<!-- 积木报表-->
|
||||||
<jimureport-spring-boot-starter.version>2.1.3</jimureport-spring-boot-starter.version>
|
<jimureport-spring-boot-starter.version>2.1.3</jimureport-spring-boot-starter.version>
|
||||||
<jimubi-spring-boot-starter.version>2.1.3</jimubi-spring-boot-starter.version>
|
<jimubi-spring-boot-starter.version>2.1.4</jimubi-spring-boot-starter.version>
|
||||||
<minidao.version>1.10.14</minidao.version>
|
<minidao.version>1.10.14</minidao.version>
|
||||||
<autopoi-web.version>1.4.18</autopoi-web.version>
|
<autopoi-web.version>1.4.18</autopoi-web.version>
|
||||||
|
|
||||||
@ -78,16 +78,13 @@
|
|||||||
<shiro.version>2.0.4</shiro.version>
|
<shiro.version>2.0.4</shiro.version>
|
||||||
<shiro-redis.version>3.2.3</shiro-redis.version>
|
<shiro-redis.version>3.2.3</shiro-redis.version>
|
||||||
<java-jwt.version>4.5.0</java-jwt.version>
|
<java-jwt.version>4.5.0</java-jwt.version>
|
||||||
<codegenerate.version>1.5.1</codegenerate.version>
|
<codegenerate.version>1.5.4</codegenerate.version>
|
||||||
<minio.version>8.5.7</minio.version>
|
<minio.version>8.5.7</minio.version>
|
||||||
<justauth-spring-boot-starter.version>1.4.0</justauth-spring-boot-starter.version>
|
<justauth-spring-boot-starter.version>1.4.0</justauth-spring-boot-starter.version>
|
||||||
<dom4j.version>1.6.1</dom4j.version>
|
<dom4j.version>1.6.1</dom4j.version>
|
||||||
<qiniu-java-sdk.version>7.4.0</qiniu-java-sdk.version>
|
<qiniu-java-sdk.version>7.4.0</qiniu-java-sdk.version>
|
||||||
<jedis.version>3.8.0</jedis.version>
|
<jedis.version>3.8.0</jedis.version>
|
||||||
<baidu-java-sdk.version>4.16.19</baidu-java-sdk.version>
|
<baidu-java-sdk.version>4.16.19</baidu-java-sdk.version>
|
||||||
<!-- spring boot 3 不支持下列两个版本-->
|
|
||||||
<!--<log4j2.version>2.17.0</log4j2.version>
|
|
||||||
<logback.version>1.4.12</logback.version>-->
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
@ -264,7 +261,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.boot3</groupId>
|
<groupId>org.jeecgframework.boot3</groupId>
|
||||||
<artifactId>hibernate-re</artifactId>
|
<artifactId>hibernate-re</artifactId>
|
||||||
<version>3.8.2</version>
|
<version>3.8.2.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- update-begin-author:chenrui -date:20240104 for:[issue/5723]指定jaxb-runtime版本 -->
|
<!-- update-begin-author:chenrui -date:20240104 for:[issue/5723]指定jaxb-runtime版本 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -432,7 +429,7 @@
|
|||||||
<!-- 积木报表-->
|
<!-- 积木报表-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
|
<artifactId>jimureport-spring-boot3-starter</artifactId>
|
||||||
<version>${jimureport-spring-boot-starter.version}</version>
|
<version>${jimureport-spring-boot-starter.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -485,7 +482,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>jimureport-nosql-starter</artifactId>
|
<artifactId>jimureport-nosql-starter</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>2.1.0</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.apache.calcite</groupId>
|
<groupId>org.apache.calcite</groupId>
|
||||||
|
|||||||
Reference in New Issue
Block a user