package cn.com.goldenwater.dcproj.target; import cn.com.goldenwater.dcproj.constValue.CommonLabel; import cn.com.goldenwater.dcproj.dao.BisInspAllRlationPersDao; import cn.com.goldenwater.dcproj.model.BisInspAllRlationPers; import cn.com.goldenwater.dcproj.utils.RequestUtils; import cn.com.goldenwater.target.CheckException; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.ApiModelProperty; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; 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 javax.servlet.http.HttpServletResponse; import java.lang.reflect.Field; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; /** * zhengdafei bean验证切面,作用域为系统中所有的实体参数 */ @Aspect @Component("verifyBeanAspect") public class VerifyBeanAspect { private static final Logger log = LoggerFactory.getLogger(VerifyBeanAspect.class); private final static String[] badSqlflag = new String[]{"$", " or", "select" , "&", " and", "drop", " 1=", "delete", "update", "from", "insert", "\\'", "execute", "dual", " order ", " by "}; @Autowired private BisInspAllRlationPersDao inspAllRlationPersDao; @Pointcut("execution(* cn.com.goldenwater.dcproj.controller..*(..)) && !execution(* cn.com.goldenwater.dcproj.controller.index..*(..))&& !execution(* cn.com.goldenwater.dcproj.controller.sso..*(..))&& !execution(* cn.com.goldenwater.dcproj.controller.ducha..*(..))&& !execution(* cn.com.goldenwater.dcproj.task..*(..))\"") // @Pointcut("@annotation(cn.com.goldenwater.dcproj.target.VerifyBean)") public void verifyBeanAspect() { } /** * 前置通知:目标方法执行之前执行以下方法体的内容 * * @param jp */ @Before(value = "verifyBeanAspect()") public void beforeMethod(JoinPoint jp) throws Exception { getAnnotationDesc(jp); } private String getAnnotationDesc(JoinPoint joinPoint) throws Exception { List args = Arrays.asList(joinPoint.getArgs()); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); String paramPersId = RequestUtils.getPersId(request, response); String orgId = request.getHeader(CommonLabel.ORGId); if ("041".equals(orgId)) { return ""; } if (args.size() > 0) { String reqPath = request.getRequestURL().toString(); if (reqPath.contains("bis/insp/key/register") || reqPath.contains("pers/position")) { //172工程先放过 return ""; } String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", ""); if (path.equals("/bis/insp/news") ) { //通知公告 放过 return ""; } String persId = request.getHeader(CommonLabel.PERSID); BisInspAllRlationPers inspAllRlationPers = inspAllRlationPersDao.get(persId); for (Object object : args) { if (object == null) { continue; } Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); //所有字符数据校验 String name = field.getName(); if ("inIdsSql".equals(name)) { continue; } String fieldStr = String.valueOf(field.get(object)); if (StringUtils.isBlank(fieldStr) || "null".equals(fieldStr)) { continue; } if ("orgId".equals(name) || "orgid".equals(name) || "persType".equals(name) || "ownerSystem".equals(name)) { if ("persType".equals(name)) { if (!"041".equals(orgId)) { if (!reqPath.contains("/sys/roles/updateRole")) { if (!fieldStr.equals(inspAllRlationPers.getPersType())) { int sysRole = Integer.parseInt(inspAllRlationPers.getPersType()); //参数权限 int paramRole = Integer.parseInt(fieldStr); if (sysRole > paramRole) { throw new CheckException("role系统存在危险操作!!"); } } } } } if ("ownerSystem".equals(name)) { if (!fieldStr.equals(inspAllRlationPers.getOwnerSystem())) { throw new CheckException("ownerSystem系统存在危险操作!!"); } } } //针对该参数的二次校验,防止系统中有遗漏 if ("persid".equals(name.toLowerCase())) { //针对特定接口进行排除。有些接口可能不需要处理 if (StringUtils.isNotBlank(fieldStr) && !"null".equals(fieldStr)) { if (StringUtils.isNotBlank(paramPersId)) { if (!fieldStr.equals(paramPersId)) { throw new CheckException("[paramPersId]:" + paramPersId + "[persId]:" + fieldStr + ",当前用户无权限执行该操作!"); } } } } ValidInValue validInValue = field.getAnnotation(ValidInValue.class); if (validInValue != null) { checkBadStr(fieldStr, field, name, object); } if (field.getAnnotation(ApiModelProperty.class) != null) { String notes = field.getAnnotation(ApiModelProperty.class).notes(); //有必填标准的数据 if (field.getAnnotation(ApiModelProperty.class).required()) { if (field.get(object) == null || "".equals(field.get(object))) { throw new CheckException(notes + "[" + name + "]不能为空:" + field.get(object)); } } else { Object fieldStr2 = field.get(object); if (fieldStr2 instanceof String) { String fieldS = String.valueOf(fieldStr2); checkBadStr(fieldS, field, name, fieldStr2); } else if (fieldStr2 instanceof List) { checkList(fieldStr2, name, field, object); } } } } } } return ""; } /** * 递归检查list内部参数 */ private void checkList(Object fieldStr2, String name, Field field, Object object) throws Exception { String jsonObject = JSONObject.toJSONString(fieldStr2); JSONArray jsonArray = JSONArray.parseArray(jsonObject); JSONObject object1 = null; for (int i = 0; i < jsonArray.size(); i++) { object1 = jsonArray.getJSONObject(i); Iterator iter = object1.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object value = entry.getValue(); if (value == null || "".equals(value)) { continue; } if (value instanceof String) { checkBadStr(String.valueOf(value), field, name, object); } else if (value instanceof List) { checkList(value, name, field, object); } } } } private void checkBadStr(String fieldStr, Field field, String name, Object object) throws Exception { if (StringUtils.isNotBlank(fieldStr)) { for (String str : badSqlflag) { if (fieldStr.contains(str)) { if (fieldStr.startsWith("[")) { continue; } throw new CheckException("[" + name + "]存在特殊字符:" + field.get(object)); } } } } }