Преглед изворни кода

增加对接应用签名校验

xuchao пре 1 месец
родитељ
комит
f90ca36d18

+ 55 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/core/sign/properties/OpenSignInterceptorProperties.java

@@ -0,0 +1,55 @@
+package vip.xiaonuo.biz.core.sign.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author 徐超
+ * @Date 2021/4/20 16:15
+ * @Version 1.0
+ */
+@Component
+@Data
+@ConfigurationProperties(prefix = "open-sign.interceptor")
+public class OpenSignInterceptorProperties {
+
+    /**
+     * 签名拦截器
+     */
+    @NestedConfigurationProperty
+    private InterceptorConfig sign = new InterceptorConfig();
+
+
+    /**
+     * 自定义权限拦截器
+     */
+    @NestedConfigurationProperty
+    private InterceptorConfig permission = new InterceptorConfig();
+
+
+    // 内部类
+    @Data
+    public static class InterceptorConfig {
+
+        /**
+         * 是否启用
+         */
+        private boolean enable;
+
+        /**
+         * 包含的路径
+         */
+        private String[] includePaths = new String[]{};
+
+        /**
+         * 排除路径
+         */
+        private String[] excludePaths = new String[]{};
+
+
+    }
+
+
+}

+ 26 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/core/sign/properties/OpenSignProperties.java

@@ -0,0 +1,26 @@
+package vip.xiaonuo.biz.core.sign.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author 徐超
+ * @Date 2021/4/20 16:39
+ * @Version 1.0
+ */
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "open-sign")
+public class OpenSignProperties {
+
+    /**
+     * 拦截器配置
+     */
+    @NestedConfigurationProperty
+    private OpenSignInterceptorProperties interceptor;
+
+
+}

+ 51 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/core/sign/utils/GenerateSignatureUtil.java

@@ -0,0 +1,51 @@
+package vip.xiaonuo.biz.core.sign.utils;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * MD5 sign签名校验宇生成工具
+ */
+public class GenerateSignatureUtil {
+
+    public static final String FIELD_SIGN = "sign";
+
+    /**
+     * 判断签名是否正确,必须包含sign字段,否则返回false。
+     *
+     * @param data Map类型数据
+     * @param key  API密钥
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(Map<String, String> data, String key) {
+        if (!data.containsKey(FIELD_SIGN)) {
+            return false;
+        }
+        String sign = data.get(FIELD_SIGN);
+        return generateSignature(data, key).equals(sign);
+    }
+
+    public static String generateSignature(final Map<String, String> data, String key) {
+        try {
+            Set<String> keySet = data.keySet();
+            String[] keyArray = keySet.toArray(new String[keySet.size()]);
+            Arrays.sort(keyArray);
+            StringBuilder sb = new StringBuilder();
+            for (String k : keyArray) {
+                if (k.equals(FIELD_SIGN)) {
+                    continue;
+                }
+                // 参数值为空,则不参与签名
+                if (data.get(k).trim().length() > 0)  {
+                    sb.append(k).append("=").append(data.get(k).trim()).append("&");
+                }
+            }
+            return MD5.md5(sb.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+}

+ 72 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/core/sign/utils/MD5.java

@@ -0,0 +1,72 @@
+package vip.xiaonuo.biz.core.sign.utils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD5 {
+
+	/**
+	 * 生成 MD5
+	 *
+	 * @param data 待处理数据
+	 * @return MD5结果
+	 */
+	public static String md5(String data) {
+		StringBuilder sb = null;
+		try {
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			byte[] array = md.digest(data.getBytes("UTF-8"));
+			sb = new StringBuilder();
+			for (byte item : array) {
+                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
+            }
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		return sb.toString().toUpperCase();
+	}
+
+
+	/**
+	 * 生成 HMACSHA256
+	 * @param data 待处理数据
+	 * @param key 密钥
+	 * @return 加密结果
+	 * @throws Exception
+	 */
+	public static String HMACSHA256(String data, String key){
+		StringBuilder sb = null;
+		try {
+			Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
+			SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
+			sha256_HMAC.init(secret_key);
+			byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
+			sb = new StringBuilder();
+			for (byte item : array) {
+                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
+            }
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		} catch (InvalidKeyException e) {
+			e.printStackTrace();
+		}
+		return sb.toString().toUpperCase();
+	}
+
+
+	public static void main(String[] args) {
+		System.out.println(md5("31119@qq.com" + "123456"));
+		System.out.println(md5("mj1"));
+		System.out.println(md5("123456"));
+		System.out.println(md5("123456"));
+
+	}
+}

+ 86 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/core/sign/utils/ServletUtils.java

@@ -0,0 +1,86 @@
+package vip.xiaonuo.biz.core.sign.utils;
+
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.io.IOException;
+
+/**
+ * 客户端工具类
+ *
+ * @author ruoyi
+ */
+public class ServletUtils {
+
+    /**
+     * 获取request
+     */
+    public static HttpServletRequest getRequest() {
+        return getRequestAttributes().getRequest();
+    }
+
+    /**
+     * 获取response
+     */
+    public static HttpServletResponse getResponse() {
+        return getRequestAttributes().getResponse();
+    }
+
+    /**
+     * 获取session
+     */
+    public static HttpSession getSession() {
+        return getRequest().getSession();
+    }
+
+    /**
+     * 获取ServletRequestAttributes
+     */
+    public static ServletRequestAttributes getRequestAttributes() {
+        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+        return (ServletRequestAttributes) attributes;
+    }
+
+    /**
+     * 将字符串渲染到客户端
+     *
+     * @param response 渲染对象
+     * @param string   待渲染的字符串
+     * @return null
+     */
+    public static String renderString(HttpServletResponse response, String string) {
+        try {
+            response.setContentType("application/json");
+            response.setCharacterEncoding("utf-8");
+            response.getWriter().print(string);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 将字符串渲染到客户端
+     *
+     * @param response 渲染对象
+     * @param string   待渲染的字符串
+     * @return null
+     */
+    public static String renderResultString(ServletResponse response, String string) {
+        try {
+            response.setContentType("application/json");
+            response.setCharacterEncoding("utf-8");
+            response.getWriter().print(string);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+}