From 4470052c3b6bdeb18e45987f8aa293d1e93d0552 Mon Sep 17 00:00:00 2001
From: Ludc <2870569285@qq.com>
Date: 星期二, 18 十一月 2025 11:59:12 +0800
Subject: [PATCH] 所有文件上传接口增加文件安全校验逻辑。
---
Source/BladeX-Tool/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladePropertySourcePostProcessor.java | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 179 insertions(+), 0 deletions(-)
diff --git a/Source/BladeX-Tool/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladePropertySourcePostProcessor.java b/Source/BladeX-Tool/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladePropertySourcePostProcessor.java
new file mode 100644
index 0000000..8ba8cca
--- /dev/null
+++ b/Source/BladeX-Tool/blade-core-launch/src/main/java/org/springblade/core/launch/props/BladePropertySourcePostProcessor.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package org.springblade.core.launch.props;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.boot.env.PropertySourceLoader;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MutablePropertySources;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.SpringFactoriesLoader;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 鑷畾涔夎祫婧愭枃浠惰鍙栵紝浼樺厛绾ф渶浣�
+ *
+ * @author L.cm
+ */
+@Slf4j
+public class BladePropertySourcePostProcessor implements BeanFactoryPostProcessor, InitializingBean, Ordered {
+ private final ResourceLoader resourceLoader;
+ private final List<PropertySourceLoader> propertySourceLoaders;
+
+ public BladePropertySourcePostProcessor() {
+ this.resourceLoader = new DefaultResourceLoader();
+ this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ log.info("BladePropertySourcePostProcessor process @BladePropertySource bean.");
+ Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(BladePropertySource.class);
+ Set<Map.Entry<String, Object>> beanEntrySet = beansWithAnnotation.entrySet();
+ // 娌℃湁 @YmlPropertySource 娉ㄨВ锛岃烦鍑�
+ if (beanEntrySet.isEmpty()) {
+ log.warn("Not found @BladePropertySource on spring bean class.");
+ return;
+ }
+ // 缁勮璧勬簮
+ List<PropertyFile> propertyFileList = new ArrayList<>();
+ for (Map.Entry<String, Object> entry : beanEntrySet) {
+ Class<?> beanClass = ClassUtils.getUserClass(entry.getValue());
+ BladePropertySource propertySource = AnnotationUtils.getAnnotation(beanClass, BladePropertySource.class);
+ if (propertySource == null) {
+ continue;
+ }
+ int order = propertySource.order();
+ boolean loadActiveProfile = propertySource.loadActiveProfile();
+ String location = propertySource.value();
+ propertyFileList.add(new PropertyFile(order, location, loadActiveProfile));
+ }
+
+ // 瑁呰浇 PropertySourceLoader
+ Map<String, PropertySourceLoader> loaderMap = new HashMap<>(16);
+ for (PropertySourceLoader loader : propertySourceLoaders) {
+ String[] loaderExtensions = loader.getFileExtensions();
+ for (String extension : loaderExtensions) {
+ loaderMap.put(extension, loader);
+ }
+ }
+ // 鍘婚噸锛屾帓搴�
+ List<PropertyFile> sortedPropertyList = propertyFileList.stream()
+ .distinct()
+ .sorted()
+ .collect(Collectors.toList());
+ ConfigurableEnvironment environment = beanFactory.getBean(ConfigurableEnvironment.class);
+ MutablePropertySources propertySources = environment.getPropertySources();
+
+ // 鍙敮鎸� activeProfiles锛屾病鏈夊繀瑕佹敮鎸� spring.profiles.include銆�
+ String[] activeProfiles = environment.getActiveProfiles();
+ ArrayList<PropertySource> propertySourceList = new ArrayList<>();
+ for (String profile : activeProfiles) {
+ for (PropertyFile propertyFile : sortedPropertyList) {
+ // 涓嶅姞杞� ActiveProfile 鐨勯厤缃枃浠�
+ if (!propertyFile.loadActiveProfile) {
+ continue;
+ }
+ String extension = propertyFile.getExtension();
+ PropertySourceLoader loader = loaderMap.get(extension);
+ if (loader == null) {
+ throw new IllegalArgumentException("Can't find PropertySourceLoader for PropertySource extension:" + extension);
+ }
+ String location = propertyFile.getLocation();
+ String filePath = StringUtils.stripFilenameExtension(location);
+ String profiledLocation = filePath + "-" + profile + "." + extension;
+ Resource resource = resourceLoader.getResource(profiledLocation);
+ loadPropertySource(profiledLocation, resource, loader, propertySourceList);
+ }
+ }
+ // 鏈韩鐨� Resource
+ for (PropertyFile propertyFile : sortedPropertyList) {
+ String extension = propertyFile.getExtension();
+ PropertySourceLoader loader = loaderMap.get(extension);
+ String location = propertyFile.getLocation();
+ Resource resource = resourceLoader.getResource(location);
+ loadPropertySource(location, resource, loader, propertySourceList);
+ }
+ // 杞瓨
+ for (PropertySource propertySource : propertySourceList) {
+ propertySources.addLast(propertySource);
+ }
+ }
+
+ private static void loadPropertySource(String location, Resource resource,
+ PropertySourceLoader loader,
+ List<PropertySource> sourceList) {
+ if (resource.exists()) {
+ String name = "bladePropertySource: [" + location + "]";
+ try {
+ sourceList.addAll(loader.load(name, resource));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ log.info("BladePropertySourcePostProcessor init.");
+ }
+
+ @Override
+ public int getOrder() {
+ return Ordered.LOWEST_PRECEDENCE;
+ }
+
+ @Getter
+ @ToString
+ @EqualsAndHashCode
+ private static class PropertyFile implements Comparable<PropertyFile> {
+ private final int order;
+ private final String location;
+ private final String extension;
+ private final boolean loadActiveProfile;
+
+ PropertyFile(int order, String location, boolean loadActiveProfile) {
+ this.order = order;
+ this.location = location;
+ this.loadActiveProfile = loadActiveProfile;
+ this.extension = Objects.requireNonNull(StringUtils.getFilenameExtension(location));
+ }
+
+ @Override
+ public int compareTo(PropertyFile other) {
+ return Integer.compare(this.order, other.order);
+ }
+ }
+}
--
Gitblit v1.9.3