src/main/java/com/ks/tool/bkz/SpringSecurityConfig.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ks/tool/bkz/aspact/PermissionValidateAspect.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ks/tool/bkz/aspact/SignValidateAspect.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ks/tool/bkz/controller/ParseController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ks/tool/bkz/util/FirstOrderSubDataUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ks/tool/bkz/util/UrlUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/resources/application.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/ks/tool/bkz/SpringSecurityConfig.java
@@ -7,8 +7,8 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity //@Configuration //@EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override src/main/java/com/ks/tool/bkz/aspact/PermissionValidateAspect.java
@@ -1,8 +1,5 @@ package com.ks.tool.bkz.aspact; import com.yeshi.fanli.util.Constant; 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; @@ -12,17 +9,13 @@ @Aspect @Order(2) public class PermissionValidateAspect { public static final String EDP = "execution(* com.ks.tool.bkz.controller.user.*.*.*(..))"; public static final String EDP = "execution(* com.ks.tool.bkz.controller.user.*.*.*(..))"; public static String KEY = ""; public static String KEY = ""; static { KEY = Constant.systemCommonConfig.getSignKey(); } static { KEY = ""; } @Around(EDP) public Object around(ProceedingJoinPoint joinPoint) throws Throwable { } } 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; } } } src/main/java/com/ks/tool/bkz/controller/ParseController.java
@@ -1,5 +1,7 @@ package com.ks.tool.bkz.controller; import com.alibaba.fastjson.JSONObject; import com.ks.tool.bkz.util.FirstOrderSubDataUtil; import com.ks.tool.bkz.util.UrlUtil; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -11,17 +13,32 @@ @RequestMapping("parse") public class ParseController { String cookie = null; @RequestMapping("getRequestUrl") @ResponseBody public String getRequestUrl(String baseUrl, String data) { public String getRequestUrl(String baseUrl) { String host = UrlUtil.getHost(baseUrl); Map<String, String> params = UrlUtil.getParamsMap(baseUrl); //获取data // if(params.put()) params.put("t", System.currentTimeMillis() + ""); String token = FirstOrderSubDataUtil.getTokenFromCookie(cookie); String data = params.get("data"); JSONObject dataJSON = JSONObject.parseObject(data); String paramsStr = dataJSON.getString("params"); dataJSON = JSONObject.parseObject(paramsStr); int pageNo = dataJSON.getInteger("pageNo"); dataJSON.put("pageNo", pageNo + 1); JSONObject paramsJSON = new JSONObject(); paramsJSON.put("params", dataJSON.toJSONString()); data = paramsJSON.toJSONString(); String sign = FirstOrderSubDataUtil.getSign(token, params.get("t"), params.get("appKey"), data); params.put("data", data); params.put("sign", sign); String requestUrl = UrlUtil.getRequestUrl(host, params); return ""; return requestUrl; } @@ -31,10 +48,9 @@ * @param cookies * @return */ @RequestMapping("uploadCookies") public String uploadCookie(String cookies) { this.cookie = cookies; return ""; } src/main/java/com/ks/tool/bkz/util/FirstOrderSubDataUtil.java
@@ -7,8 +7,10 @@ import com.ks.tool.bkz.dto.FirstOrderSubInfoDTO; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class FirstOrderSubDataUtil { @@ -44,9 +46,25 @@ * @param data * @return */ public static String getSign(String token, long time, String appKey, String data) { public static String getSign(String token, String time, String appKey, String data) { return StringUtil.Md5(String.format("%s&%s&%s&%s", token, time, appKey, data)); } /** * 获取token * @param cookie * @return */ public static String getTokenFromCookie(String cookie) { Map<String, String> map = new HashMap<>(); String[] sts = cookie.split(";"); for (String st : sts) { map.put(st.split("=")[0].trim(), st.split("=")[1].trim()); } String tk = map.get("_m_h5_tk"); return tk.split("_")[0]; } } src/main/java/com/ks/tool/bkz/util/UrlUtil.java
@@ -1,6 +1,9 @@ package com.ks.tool.bkz.util; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class UrlUtil { @@ -37,4 +40,27 @@ } return null; } /** * 获取请求链接 * @param url * @param params * @return */ public static String getRequestUrl(String url, Map<String, String> params) { String URL = url; for (Iterator<String> its = params.keySet().iterator(); its.hasNext(); ) { String key = its.next(); try { URL += key + "=" + URLEncoder.encode(params.get(key), "UTF-8") + "&"; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } if (URL.endsWith("&")) URL = URL.substring(0, URL.length() - 1); return URL; } } src/main/resources/application.yml
@@ -1,59 +1,2 @@ server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/uqi-user username: root password: 123456 # 使用druid数据源 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver filters: stat maxActive: 20 initialSize: 1 maxWait: 60000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 maxOpenPreparedStatements: 20 data: mongodb: host: 192.168.1.253 port: 27017 database: bkz username: admin password: 123456 redis: database: 0 host: 192.168.0.24 port: 6379 # Redis服务器连接密码(默认为空) password: # 连接池最大连接数(使用负值表示没有限制) pool.max-active: 200 # 连接池最大阻塞等待时间(使用负值表示没有限制) pool.max-wait: -1 # 连接池中的最大空闲连接 pool.max-idle: 10 # 连接池中的最小空闲连接 pool.min-idle: 0 # 连接超时时间(毫秒) timeout: 1000 mybatis: mapper-locations: classpath:mapping/*.xml type-aliases-package: com.uqiauto.user.model mapper: mappers: com.ks.tool.dao.mapper not-empty: false identity: MYSQL port: 8082