admin
2020-06-03 48919e675b01fba353b36e98df7ebbbf9ef4e984
src/main/java/com/ks/tool/bkz/aspact/SignValidateAspect.java
@@ -1,232 +1,21 @@
package com.ks.tool.bkz.aspact;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.util.*;
//客户端接口签名验证
@Component
@Aspect
@Order(1)
public class SignValidateAspect {
   public static final String EDP = "execution(* com.ks.tool.bkz.controller.*.*.*(..))";
    public static final String EDP = "execution(* com.ks.tool.bkz.controller.*.*.*(..))";
   public static String KEY = "";
    public static String KEY = "";
   static {
      KEY = Constant.systemCommonConfig.getSignKey();
   }
    static {
        KEY = "";
    }
   @Around(EDP)
   public Object testAround(ProceedingJoinPoint joinPoint) throws Throwable {
      Object[] args = joinPoint.getArgs();
      PrintWriter out = null;
      ServletRequestAttributes servletContainer = (ServletRequestAttributes) RequestContextHolder
            .getRequestAttributes();
      out = servletContainer.getResponse().getWriter();
      HttpServletRequest request = servletContainer.getRequest();
      AcceptData acceptData = null;
      for (Object obj : args) {
         if (obj instanceof AcceptData) {
            acceptData = (AcceptData) obj;
         } else if (obj instanceof HttpServletRequest) {
            request = (HttpServletRequest) obj;
         }
      }
      boolean isRight = true;
      if (acceptData == null) {
         out.print(JsonUtil.loadFalseResult(-1, "签名错误"));
         return null;
      }
      isRight = false;
      if ((acceptData.getPlatform() != null && acceptData.getPlatform().equalsIgnoreCase("android")
            && acceptData.getVersion() != null && Integer.parseInt(acceptData.getVersion()) > 21)
            || (acceptData.getPlatform() != null && acceptData.getPlatform().equalsIgnoreCase("ios")
                  && acceptData.getVersion() != null && Integer.parseInt(acceptData.getVersion()) > 24)) {
         isRight = signIsRight(request);
      } else if (acceptData.getPackages().startsWith("com.haicaojie")) {
         isRight = signIsRight(request);
      } else {
         isRight = signIsRight(acceptData);
      }
      // if (Integer.parseInt(acceptData.getVersion()) > 21) {
      // isRight = signIsRight(request);
      // } else {
      // isRight = signIsRight(acceptData);
      // }
      // 签名是否正确
      if (isRight) {
         // 判断签名超时
         if (Math.abs((Long.parseLong(acceptData.getTime()) - System.currentTimeMillis())) > 1000 * 60 * 10) {
            JSONObject data = new JSONObject();
            data.put("code", -2);
            data.put("msg", "时间错误");
            out.print(data);
            out.close();
            return null;
         }
         final String url = request.getRequestURI();
         @SuppressWarnings("unchecked")
         final Map<String, Object> params = request.getParameterMap();
         ThreadUtil.run(new Runnable() {
            @Override
            public void run() {
               // 记录请求日志
               LogHelper.requestInfo(url, params);
            }
         });
         Object obj = null;
         try {
            long startTime = System.currentTimeMillis();
            obj = joinPoint.proceed(args);
            final long responseTime = System.currentTimeMillis() - startTime;
            // 记录大于2s的请求
            if (responseTime >= 2000) {
               ThreadUtil.run(new Runnable() {
                  @Override
                  public void run() {
                     LogHelper.requestTime(url, params, responseTime);
                  }
               });
            }
         } catch (Throwable e) {
            LogHelper.errorDetailInfo(e, getHttpServletParams(request), request.getRequestURI().toString());
            if (!Constant.IS_TEST)
               out.print(JsonUtil.loadFalseResult(90009, "服务器内部错误"));
            else
               throw e;
         }
         return obj;
      } else {
         JSONObject data = new JSONObject();
         data.put("code", -1);
         data.put("msg", "签名错误");
         out.print(data);
         out.close();
         LogHelper.error("签名错误:" + request.getRequestURI() + "-" + getHttpServletParams(request));
         return null;
      }
   }
   private String getHttpServletParams(HttpServletRequest request) {
      if (request == null) {
         return "";
      }
      Map map = request.getParameterMap();
      if (map != null) {
         Iterator<String> its = map.keySet().iterator();
         JSONObject json = new JSONObject();
         while (its.hasNext()) {
            String next = its.next();
            if (map.get(next) != null) {
               Object[] objects = (Object[]) map.get(next);
               if (objects != null && objects.length > 0) {
                  json.put(next, objects[0].toString());
               }
            }
         }
         return json.toString();
      }
      return "";
   }
   private boolean signIsRight(AcceptData acceptData) {
      String[] arr = new String[] { acceptData.getApiversion(), acceptData.getAppkey(), acceptData.getDevice(),
            acceptData.getPackages(), acceptData.getPlatform(), acceptData.getTime(), acceptData.getVersion() };
      Arrays.sort(arr);
      StringBuffer sb = new StringBuffer();
      for (String val : arr) {
         sb.append(val);
      }
      String md5 = StringUtil.Md5(sb.toString() + KEY);
      if (!md5.equals(acceptData.getSign())) {
         return false;
      } else {
         return true;
      }
   }
   /**
    * 判断签名的正确性 Android version>50
    *
    * @param request
    * @return
    */
   @SuppressWarnings("unchecked")
   private boolean signIsRight(HttpServletRequest request) {
      Map<String, Object> map = request.getParameterMap();
      Iterator<String> its = map.keySet().iterator();
      List<String> list = new ArrayList<>();
      boolean fromWEB = false;
      while (its.hasNext()) {
         String key = its.next();
         // if (key.equalsIgnoreCase("callback")) {
         // fromWEB = true;
         // }
         if (key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("callback") || key.equalsIgnoreCase("_")) {
            continue;
         }
         Object value = map.get(key);
         Object[] values = (Object[]) value;
         list.add(key + "=" + values[0].toString());
      }
      Collections.sort(list);
      String str = "";
      for (String st : list) {
         str += st + "&";
      }
      String sign = null;
      if (!fromWEB)
         sign = StringUtil.Md5(str + KEY);
      else
         sign = StringUtil.Md5(str + Constant.WEBPAGE_SIGN_KEY);
      if (sign.equalsIgnoreCase(request.getParameter("sign") + "")) {
         return true;
      } else {
         return false;
      }
   }
   public static boolean signIsRight(JSONObject json) {
      List<String> list = new ArrayList<>();
      for (Iterator<String> its = json.keySet().iterator(); its.hasNext();) {
         String key = its.next();
         if (!key.equalsIgnoreCase("sign"))
            list.add(key + "=" + json.optString(key));
      }
      Collections.sort(list);
      String str = "";
      for (String st : list) {
         str += st + "&";
      }
      String sign = StringUtil.Md5(str + KEY);
      if (sign.equalsIgnoreCase(json.optString("sign"))) {
         return true;
      } else {
         return false;
      }
   }
}