New file |
| | |
| | | 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 String KEY = ""; |
| | | |
| | | static { |
| | | KEY = Constant.systemCommonConfig.getSignKey(); |
| | | } |
| | | |
| | | @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; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |