aop拦截指定参数

package com.jzlife.management.aop;


import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.jzlife.management.util.ConstantEnum;

@Target({ElementType.PARAMETER, ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented 
public @interface OpermClass  {
	  
	ConstantEnum[] orgCode() default {};
	
	ConstantEnum[] prmClass() default {} ;
	
	String parmName() default "";
}
package com.jzlife.management.aop;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

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.aspectj.lang.reflect.MethodSignature;
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 com.jzlife.management.entity.perm.PermClass;
import com.jzlife.management.entity.perm.PermClassOptype;
import com.jzlife.management.entity.perm.PermObj;
import com.jzlife.management.entity.perm.PermObjGroup;
import com.jzlife.management.entity.perm.PermRoleOrg;
import com.jzlife.management.entity.perm.PermRoleOrgNode;
import com.jzlife.management.entity.sys.SysUser;
import com.jzlife.management.util.ConstantEnum;
import com.jzlife.management.util.JsonUtil;
import com.jzlife.management.util.RedisDataUtil;


@Aspect
@Component
public class PermClassAspect {

	//@PermClass(parmName="stageIdsNotNull",orgCode="orgCode111",prmClass="permClass2222")
	@Autowired
	RedisDataUtil redisDataUtil;


	@Pointcut("execution(* com.jzlife.management.web..*.*(..))")  
	public  void controllerAspect() {  
	} 

	@Before("controllerAspect()")  
	public  void doBefore(JoinPoint joinPoint) { 
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		// HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

		String url = request.getRequestURI();
		String url2 = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("?") == -1 ? url.length() : url.lastIndexOf("?"));


		MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
		Method method = methodSignature.getMethod();

		if(method.isAnnotationPresent(OpermClass.class)){

			OpermClass perm=method.getAnnotation(OpermClass.class);
			String orgCode= perm.orgCode()[0].code;//组织树code
			String prmClassCode=perm.prmClass()[0].code;//权限类
			String parmName = perm.parmName();
			String token = request.getHeader("token");//当前人的token
			List<Object> listobj=new ArrayList<Object>();//获取到的最小业务id 

			Object parameObj=request.getParameter(parmName);//requestParame参数
			listobj=getObjId(parameObj);
			if(listobj.size()==0) {//如果没有requestParame就从body获取
				Object[] bodyObj = joinPoint.getArgs();//body格式参数
				listobj= getBodyId(bodyObj, parmName);
			}
			//			if(listobj.size()==0) {
			//				return;
			//			}


			String checkMsg=null;
			try {
				checkMsg=checkPerm(token, parmName, orgCode, prmClassCode,url2,listobj);				
			} catch (Exception e) {
				e.printStackTrace();
				checkMsg="权限验证异常!";
			} 
			if(null!=checkMsg) {
				System.out.println("权限不通过:"+checkMsg);
				throw new RuntimeException("权限不通过:"+checkMsg);
			}

		} 

	}

	/**
	 * 验证权限
	 * @param token
	 * @param parmName
	 * @param orgCode
	 * @param prmClassCode
	 * @param url
	 * @param listobj
	 * @return
	 */
	public String checkPerm(String token,String parmName,String orgCode,String prmClassCode,String url,List<Object> listobj) {
		if(null==token) {
			return "用户没登陆或登陆身份过时";//用户没登陆或登陆数据过时
		}
		
		SysUser currUser = redisDataUtil.getCurrUser(token);
		if(null==currUser) {
			return "用户没登陆或登陆身份过时";//用户没登陆或登陆数据过时
		}

		Map<Object, Object> userAuth = redisDataUtil.getUserAuth(currUser.getUserAccount());

		List<PermRoleOrg> sysRoleOrg= (List<PermRoleOrg>) userAuth.get("sysRoleOrg");//系统所有组织
		List<PermRoleOrgNode> role = (List<PermRoleOrgNode>) userAuth.get("roleOrgNode");//用户拥有的组织树
		List<PermClass> permClasslist= (List<PermClass>) userAuth.get("permClassList");//用户角色组织树 拥有的权限类

		//拿到系统组织树对应的id
		Long orgTrueId=null;
		for(PermRoleOrg rg:sysRoleOrg) {
			if(rg.getOrgCode().equals(orgCode)) {
				orgTrueId=rg.getId();
			}
		}
		if(orgTrueId==null) {
			return "系统不存在该组织树"+orgCode;//系统没有该组织树
		}

		//看用户有没有这个组织树id,并把组织树的角色对应的保存
		List<PermRoleOrgNode> usRoleClass=new ArrayList<PermRoleOrgNode>();//当前组织树下的角色
		for(PermRoleOrgNode pr:role) {
			if(pr.getOrgId().equals(orgTrueId)) {
				usRoleClass.add(pr);
			}
		}
		if(usRoleClass.size()==0) {//用户没有组织树
			return "用户没有该组织树"+orgCode;
		}

		//注意:一个角色对应一个权限类,一个组织树中的角色是唯一的,(但一个权限类可被多个角色绑定)
		//从用户的组织树对应的角色,找到角色对应权限类
		String ckstr=null;
		for(PermRoleOrgNode u:usRoleClass) {
			for(PermClass p:permClasslist) {
				//如果用户组织树下的存在该权限类的角色,且数据存在,和操作类型存在
				if(u.getRoleId().equals(p.getPermRoleClass().getRoleId())&&prmClassCode.equals(p.getClsCode())) {
					ckstr= checkDataOptType(url, listobj, p,prmClassCode);
					if(null==ckstr) { //唯一验证通过,最后一步
						return null;
					}
				} 
			}
		} 

		return ckstr;

	}

	//验证数据范围和操作类型
	private String checkDataOptType(String url, List<Object> listobj, PermClass p,String prmClassCode) {
		boolean databoo=true;//数据范围
		boolean opttypeboo=false;//操作类型
		for(PermClassOptype cot:p.getPermClassOptype()) {//操作类型是否存在
			if(url.startsWith(cot.getOptCode())) {
				opttypeboo=true;
				if(!cot.getOptCode().equals("select")&&!cot.getOptCode().equals("find")) {
					//如果是编辑类的update,delete,insert,不验证数据范围;
					return null;
				}
				break;
			}
		}

		List<PermObjGroup> permObjGroupList = p.getPermObjGroupList();
		List<PermObj> tempPermObjList=new ArrayList<PermObj>();//拿到角色对应的权限类下的对象组的最小业务id(对象锁)
		for(PermObjGroup g:permObjGroupList) {
			tempPermObjList.addAll(g.getPermObjList());
		}

		//					List<Object> listobj
		for(Object o:listobj) {
			boolean checkboo=false;
			for(PermObj permobj:tempPermObjList) {
				if(prmClassCode.equals(ConstantEnum.PERM_CLASS_WAREHOUSE.getCode())) {//仓库是用code校验
					if(o.toString().equals(permobj.getRefCode())) {
						checkboo=true;
					}
				}else{
					if(permobj.getRefId().equals(Long.parseLong(o.toString()))) {
						checkboo=true;
					}
				}
			}
			if(checkboo==false) {
				databoo=false;//有一个数据不存在就提示权限不够
				break;
			}
		}

		if(databoo==false) {
			return "数据范围不够";
		}
		if(opttypeboo==false) {
			return "操作类型不够";
		}
		
		return null;
	}

	@SuppressWarnings("unchecked")
	public List<Object> getBodyId(Object[] bodyObj,String key) {
		List<Object> list=new ArrayList<Object>();
		for(Object o:bodyObj) {//拿到body参数,只有一级
			if(null==o){
				continue;
			}
			if(o instanceof Integer) {
				continue;
			}
			if(o instanceof String) {
				continue;
			}
			whileObj(key, list, o);
		}
		return list;
	}

	private void whileObj(String key, List<Object> list, Object o) {
		Map<Object,Object> map = JsonUtil.getEntity(o, Map.class);
		if(null==map) {
			return ;
		}

		if(map.containsKey(key)) {
			List<Object> objId = getObjId(map.get(key));
			list.addAll(objId);
			return ;
		}
		for(Entry<Object, Object>  entry:map.entrySet()) {

			//			if(map.get(mkey) instanceof Map) {
			//				whileObj(key, list,map.get(mkey));
			//			}

			//			if(null!=map.get(entry.getKey())) {
			//				System.out.println(map.get(entry.getKey()).getClass());
			//			}

			if(null!=map.get(entry.getKey()) && map.get(entry.getKey()) instanceof ArrayList) {
				System.out.println("List");
				List<Object> templist=(List<Object>) map.get(entry.getKey());
				for(Object s:templist) {
					whileObj(key, list,s);
				}
			}
		}
	}


	public  List<Object>  getObjId(Object obj) {
		List<Object> list=new ArrayList<Object>();
		if(null!=obj&&!"".equals(obj)) {
			if(obj instanceof ArrayList) {
				list.addAll((List)obj);
			}

			if(obj instanceof String) {
				//				System.out.println("String"+obj.toString().split(",").length);
				Object []temp=((String) obj).split(",");
				List<Object> asList = Arrays.asList(temp);
				if(null!=asList&&asList.size()>0) {
					list.addAll(Arrays.asList(temp));
				}
			}

		}
		return list;

	}


}

 

package com.jzlife.management.util;

public enum ConstantEnum {

	//权限类模块代码
	PERM_CLASS_CITY("perm_class_city_model_code","全国城市"),
	PERM_CLASS_STATION("perm_class_station_model_code","全国驿站"),
	PERM_CLASS_WAREHOUSE("perm_class_warehouse_mode_code","仓库"),
	
	//组织树
	PERM_ORGTREE_WRK_ENTRY("wrk_entry","招商"),
	PERM_ORGTREE_WRK_ONBOARD("wrk_entry","商家签约"),
	PERM_ORGTREE_WRK_MANAGE("wrk_manage","商家管理"),
	PERM_ORGTREE_OP_MASTER("op_master","师徒"),
	PERM_ORGTREE_OP_SACTION("op_saction","奖罚"),
	PERM_ORGTREE_OP_PAYMENT("op_payment","薪资"),
	PERM_ORGTREE_RM_BUILDING("rm_building","租房"),
	PERM_ORGTREE_RM_DORM("rm_dorm","宿舍"),
	PERM_ORGTREE_RM_TENANT("rm_tenant","入住"),
	PERM_ORGTREE_CMN_STAGE("cmn_stage","服务站"),
	PERM_ORGTREE_TRN_COURSE("trn_course","课程设置"),
	PERM_ORGTREE_TRN_TEACHER("trn_teacher","讲师"),
	PERM_ORGTREE_TRN_CLASSROOM("trn_classroom","实操房"),
	PERM_ORGTREE_TRN_ARRANGE("trn_arrange","排课"),
	PERM_ORGTREE_TRN_ENROLL("trn_enroll","报课"),
	PERM_ORGTREE_TRN_TRAINING("trn_training","授课"),
	PERM_ORGTREE_TRN_ONJOB("trn_onjob","跟单"),
	PERM_ORGTREE_MAT_MATERIAL("mat_material","物料设置"),
	PERM_ORGTREE_MAT_WAREHOUSE("mat_warehouse","仓库设置"),
	PERM_ORGTREE_MAT_STOCK("mat_stock","库存管理"),
	PERM_ORGTREE_MAT_ORDER("mat_order","物料申领"),
	PERM_ORGTREE_MAT_LEASE("mat_lease","租赁"),
	
	
	ROLE_STATION_MAST("stationadmin","服务站负责人");//服务站负责人
	 
	public  String code;
	public  String disc;

	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getDisc() {
		return disc;
	}
	public void setDisc(String disc) {
		this.disc = disc;
	}

	public static String getDiscStr(String code) {
		ConstantEnum[] values = ConstantEnum.values();
		for(ConstantEnum s:values) {
			if(s.getCode().equals(code)) {
				return s.getDisc();
			}
		}
		return null;
	}
	
	private ConstantEnum(String code, String disc) {
		this.code = code;
		this.disc = disc;
	}


}

使用注解到controller方法前@OpermClass(parmName = "cityIds", orgCode = ConstantEnum.PERM_ORGTREE_TRN_ARRANGE, prmClass = ConstantEnum.PERM_CLASS_CITY)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值