@Documented
@Inherited
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface AclValide {
String url() default "";
}
@Aspect
@Component
public class AclValideAspect {
private static Logger logger = LoggerFactory.getLogger(AclValideAspect.class);
//配置切入点 只对配置AclValide注解的接口进行切入
@Pointcut("@annotation(com.hanshow.wise.base.privileges.annotation.AclValide)")
public void controllerAspect() {
logger.info("ACL注解权限拦截切入点加载");
}
//在执行方法前获取AclValide配置的url地址,与redis缓存中的权限集合比对,判断用户是否拥有此权限访问该接口
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {
logger.info("=====AclValideAspect前置通知开始=====");
// 访问目标方法参数,有三种方法(实际有四种)
// 1.joinpoint.getargs():获取带参方法的参数
// 2.joinpoint.getTarget():.获取他们的目标对象信息
// 3..joinpoint.getSignature():(signature是信号,标识的意思):获取被增强的方法相关信息
Object[] args = joinPoint.getArgs();
if (args == null) {
//controller请求地址没有参数直接放行
logger.info("请求接口没有参数,不进行权限校验");
return;
}
//获取请求头参数
BaseQUERY baseQUERY = null;
for (int i = 0; i < args.length; i++) {
Object obj = args[i];
//请求参数中其中一个是JSONObject
if (obj instanceof JSONObject) {
baseQUERY = JSON.parseObject(JSON.toJSONString(obj), BaseQUERY.class);
if (baseQUERY == null || StringUtil.isEmptyTrim(baseQUERY.getMerchantId()) || StringUtil.isEmptyTrim(baseQUERY.getUserId())) {
logger.info("请求头数据不全,merchantId={},userId={},request={},不进行权限校验", baseQUERY.getMerchantId(), baseQUERY.getUserId(), JSON.toJSONString(baseQUERY));
return;
}
break;
} else if (obj instanceof BaseQUERY) {
//请求参数中其中一个是BaseQUERY
baseQUERY = (BaseQUERY) obj;
if (StringUtil.isEmptyTrim(baseQUERY.getMerchantId()) || StringUtil.isEmptyTrim(baseQUERY.getUserId())) {
logger.info("请求头数据不全,merchantId={},userId={},request={},不进行权限校验", baseQUERY.getMerchantId(), baseQUERY.getUserId(), JSON.toJSONString(baseQUERY));
return;
}
break;
}
}
//请求接口有参数,但是参数类型没有JSONObject,BaseQUERY两种的任何一种
if (baseQUERY == null) {
logger.info("请求接口有参数,但是参数类型没有JSONObject,BaseQUERY两种的任何一种,不进行权限校验");
return;
}
//获取注解方法参数值
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
AclValide aclValideAnnotation = method.getAnnotation(AclValide.class);
//权限在缓存中的key值
String resourcePathkey = AspectConstant.PRIVILEGES_PICK_CENTER_SIMPLE + baseQUERY.getMerchantId() + "" + baseQUERY.getUserId();
Long listLength = RedisUtil.getListLength(resourcePathkey);
if (listLength == null) {
logger.info("从缓存获取权限集合长度失败,resourcePathkey={},不进行权限校验", resourcePathkey);
return;
}
List list = RedisUtil.getList(resourcePathkey, 0, listLength);
if (list == null) {
logger.info("从缓存获取权限集合失败,resourcePathkey={},不进行权限校验", resourcePathkey);
} else {
if (list.contains(aclValideAnnotation.url())) {
//符合权限放行
} else {
throw new WiseException(JSON.toJSONString(BaseDTO.genErrBaseDTO(baseQUERY, BaseError.E10_PERMISSION_DENIED)));
}
}
}
}
@AclValide(url = "/resource/getTree")
@RequestMapping(value = "/resource/getTree", method = RequestMethod.POST)
@ResponseBody
public Object getTree(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
}
@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {
private static Logger logger = LoggerFactory.getLogger(CustomExceptionResolver.class);
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
ModelAndView modelAndView = new ModelAndView();
response.setStatus(HttpStatus.OK.value()); //设置状态码
response.setContentType(MediaType.APPLICATION_JSON_VALUE); //设置ContentType
response.setCharacterEncoding("UTF-8"); //避免乱码
response.setHeader("Cache-Control", "no-cache, must-revalidate");
try {
if (exception instanceof WiseException) {
WiseException wiseException = (WiseException) exception;
response.getWriter().write(wiseException.getMessage());
logger.error("全局异常处理类捕捉到异常:" + wiseException.getMessage());
} else {
BaseDTO