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-cloud/src/main/java/org/springblade/core/cloud/sentinel/BladeSentinelInvocationHandler.java | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 169 insertions(+), 0 deletions(-)
diff --git a/Source/BladeX-Tool/blade-core-cloud/src/main/java/org/springblade/core/cloud/sentinel/BladeSentinelInvocationHandler.java b/Source/BladeX-Tool/blade-core-cloud/src/main/java/org/springblade/core/cloud/sentinel/BladeSentinelInvocationHandler.java
new file mode 100644
index 0000000..7a83969
--- /dev/null
+++ b/Source/BladeX-Tool/blade-core-cloud/src/main/java/org/springblade/core/cloud/sentinel/BladeSentinelInvocationHandler.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2018-2028, Chill Zhuang 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: Chill 搴勯獮 (smallchill@163.com)
+ */
+package org.springblade.core.cloud.sentinel;
+
+import com.alibaba.cloud.sentinel.feign.SentinelContractHolder;
+import com.alibaba.csp.sentinel.Entry;
+import com.alibaba.csp.sentinel.EntryType;
+import com.alibaba.csp.sentinel.SphU;
+import com.alibaba.csp.sentinel.Tracer;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import feign.Feign;
+import feign.InvocationHandlerFactory;
+import feign.MethodMetadata;
+import feign.Target;
+import org.springframework.cloud.openfeign.FallbackFactory;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static feign.Util.checkNotNull;
+
+/**
+ * 閲嶅啓 {@link com.alibaba.cloud.sentinel.feign.SentinelInvocationHandler} 閫傞厤鏈�鏂癆PI
+ *
+ * @author Chill
+ */
+public class BladeSentinelInvocationHandler implements InvocationHandler {
+
+ private final Target<?> target;
+
+ private final Map<Method, InvocationHandlerFactory.MethodHandler> dispatch;
+
+ private FallbackFactory fallbackFactory;
+
+ private Map<Method, Method> fallbackMethodMap;
+
+ public BladeSentinelInvocationHandler(Target<?> target, Map<Method, InvocationHandlerFactory.MethodHandler> dispatch,
+ FallbackFactory fallbackFactory) {
+ this.target = checkNotNull(target, "target");
+ this.dispatch = checkNotNull(dispatch, "dispatch");
+ this.fallbackFactory = fallbackFactory;
+ this.fallbackMethodMap = toFallbackMethod(dispatch);
+ }
+
+ public BladeSentinelInvocationHandler(Target<?> target, Map<Method, InvocationHandlerFactory.MethodHandler> dispatch) {
+ this.target = checkNotNull(target, "target");
+ this.dispatch = checkNotNull(dispatch, "dispatch");
+ }
+
+ @Override
+ public Object invoke(final Object proxy, final Method method, final Object[] args)
+ throws Throwable {
+ if ("equals".equals(method.getName())) {
+ try {
+ Object otherHandler = args.length > 0 && args[0] != null
+ ? Proxy.getInvocationHandler(args[0]) : null;
+ return equals(otherHandler);
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ } else if ("hashCode".equals(method.getName())) {
+ return hashCode();
+ } else if ("toString".equals(method.getName())) {
+ return toString();
+ }
+
+ Object result;
+ InvocationHandlerFactory.MethodHandler methodHandler = this.dispatch.get(method);
+ // only handle by HardCodedTarget
+ if (target instanceof Target.HardCodedTarget) {
+ Target.HardCodedTarget hardCodedTarget = (Target.HardCodedTarget) target;
+ MethodMetadata methodMetadata = SentinelContractHolder.METADATA_MAP
+ .get(hardCodedTarget.type().getName()
+ + Feign.configKey(hardCodedTarget.type(), method));
+ // resource default is HttpMethod:protocol://url
+ if (methodMetadata == null) {
+ result = methodHandler.invoke(args);
+ } else {
+ String resourceName = methodMetadata.template().method().toUpperCase()
+ + ":" + hardCodedTarget.url() + methodMetadata.template().path();
+ Entry entry = null;
+ try {
+ ContextUtil.enter(resourceName);
+ entry = SphU.entry(resourceName, EntryType.OUT, 1, args);
+ result = methodHandler.invoke(args);
+ } catch (Throwable ex) {
+ // fallback handle
+ if (!BlockException.isBlockException(ex)) {
+ Tracer.trace(ex);
+ }
+ if (fallbackFactory != null) {
+ try {
+ Object fallbackResult = fallbackMethodMap.get(method)
+ .invoke(fallbackFactory.create(ex), args);
+ return fallbackResult;
+ } catch (IllegalAccessException e) {
+ // shouldn't happen as method is public due to being an
+ // interface
+ throw new AssertionError(e);
+ } catch (InvocationTargetException e) {
+ throw new AssertionError(e.getCause());
+ }
+ } else {
+ // throw exception if fallbackFactory is null
+ throw ex;
+ }
+ } finally {
+ if (entry != null) {
+ entry.exit(1, args);
+ }
+ ContextUtil.exit();
+ }
+ }
+ } else {
+ // other target type using default strategy
+ result = methodHandler.invoke(args);
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof BladeSentinelInvocationHandler) {
+ BladeSentinelInvocationHandler other = (BladeSentinelInvocationHandler) obj;
+ return target.equals(other.target);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return target.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+
+ static Map<Method, Method> toFallbackMethod(Map<Method, InvocationHandlerFactory.MethodHandler> dispatch) {
+ Map<Method, Method> result = new LinkedHashMap<>();
+ for (Method method : dispatch.keySet()) {
+ method.setAccessible(true);
+ result.put(method, method);
+ }
+ return result;
+ }
+
+}
--
Gitblit v1.9.3