接口安全校验

    科技2025-05-05  12

    文章目录

    自定义鉴权注解AuthCheck.java加密辅助类SignUtil.javaapi拦截器ApiInterceptor.java

    自定义鉴权注解AuthCheck.java

    import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义鉴权注解 * @author * */ @Documented @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AuthCheck { boolean validate() default true; }

    加密辅助类SignUtil.java

    import java.util.ArrayList; import java.util.Arrays; import java.util.Map; /** * 加密辅助类 * @author * @time 2016-2-25 */ public class SignUtil { private static String key = "IXCfWBE5dRfyuIcFmhe2ANQ6VmoRZxRP"; public static String getSign(Map<String,Object> map) throws Exception{ ArrayList<String> list = new ArrayList<String>(); for(Map.Entry<String,Object> entry:map.entrySet()){ if(!entry.getValue().equals("")&& !entry.getKey().equals("sign")){ list.add(entry.getKey() + "=" + entry.getValue() + "&"); } } int size = list.size(); String [] arrayToSort = list.toArray(new String[size]); //先按照字符串长度取短的那个字符串的长度作为条件,然后循环判断两个字符串的第一个字符的ASCII码大小,做出递增排序,如果两个字符串第一个字符的ASCII码一致,则判断第二个字符,以此类推,通过这种方式将字符串通过首字母的ASCII码进行排序。 Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER); StringBuilder sb = new StringBuilder(); for(int i = 0; i < size; i ++) { sb.append(arrayToSort[i]); } String result = sb.toString(); result += "key=" + key; result = MD5Encrypt.encrypt(result).toUpperCase(); return result; } }

    api拦截器ApiInterceptor.java

    import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; /** * api 拦截器 * @author * */ public class ApiInterceptor extends HandlerInterceptorAdapter { private static Logger logger = LoggerFactory.getLogger(ApiInterceptor.class); // 10分钟有效请求时间 private static final long REQUEST_TIMEOUT_EXPIRE = 10 * 60 * 1000; private static final String UTF8 = "utf-8"; private static final String CONTENT_TYPE = "application/json"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; // 签名比较 String sign = request.getParameter("sign"); if(handler.getClass().isAssignableFrom(HandlerMethod.class)){ AuthCheck authCheck = ((HandlerMethod) handler).getMethodAnnotation(AuthCheck.class); //没有声明需要权限,或者声明不验证权限 if(authCheck == null || authCheck.validate() == false){ return true; }else{ String timestamp = request.getParameter("timestamp"); // 时间戳参数检查 if (StringUtils.isBlank(timestamp)) { logger.error("签名参数timestamp'{}'为空 requestInfo:{}", timestamp, request.getServletPath()); responseJson(response, "{\"flag\":false,\""+Constants.STATUS+"\":"+CodeConstants.CONNCODECHECK+",\"msg\":\"非法请求,服务器已拒绝!\"}"); return false; } // 请求失效检查 long clientTimestamp = new Long(timestamp); if (!(Math.abs(System.currentTimeMillis() - clientTimestamp) < REQUEST_TIMEOUT_EXPIRE)) { logger.error("请求已过期 clientTimestampStr:{} requestInfo:{}", timestamp, request.getServletPath()); responseJson(response, "{\"flag\":false,\""+Constants.STATUS+"\":"+CodeConstants.CONNCODECHECK+",\"msg\":\"非法请求,服务器已拒绝!\"}"); return false; } // 服务端签名 String serverSign; // 服务端签名参数 Map<String, Object> paramMap = new HashMap<String, Object>(); Map<String, String[]> parameterMap = request.getParameterMap(); for (String key : parameterMap.keySet()) { paramMap.put(key, getParamValue(parameterMap.get(key))); } serverSign = SignUtil.getSign(paramMap); //在这里实现自己的权限验证逻辑 if (StringUtils.isBlank(serverSign) || !serverSign.equals(sign)) {//如果验证失败 logger.error("签名不一致 serverSign:{} clientSign:{} requestInfo:{}", new Object[] { serverSign, sign, request.getServletPath() }); responseJson(response, "{\"flag\":false,\""+Constants.STATUS+"\":"+CodeConstants.CONNCODECHECK+",\"msg\":\"非法请求,服务器已拒绝!\"}"); return false; }else{ //校验成功 return true; } } } else return true; } /** * 获取请求中的所有参数 * @param paramValues * @return */ private String getParamValue(String[] paramValues) { if (paramValues == null) { return StringUtils.EMPTY; } String paramValue = null; if (paramValues.length == 1) { paramValue = paramValues[0]; } else if (paramValues.length > 1) { paramValue = StringUtils.join(paramValues, ","); } return StringUtils.defaultString(paramValue); } public static void responseJson(HttpServletResponse response, String responseContent) throws IOException { if (response.isCommitted()) { logger.info("response.isCommitted()! responseContent:{"+responseContent+"}"); return; } response.setCharacterEncoding(UTF8); response.setContentType(CONTENT_TYPE); PrintWriter printWriter = response.getWriter(); printWriter.print(responseContent); printWriter.flush(); printWriter.close(); } }
    Processed: 0.042, SQL: 8