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)