package com.qianwen.core.secure.aspect; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import com.qianwen.core.secure.annotation.PreAuth; import com.qianwen.core.secure.auth.AuthFun; import com.qianwen.core.secure.exception.SecureException; import com.qianwen.core.secure.utils.AuthUtil; import com.qianwen.core.tool.api.ResultCode; import com.qianwen.core.tool.utils.ClassUtil; import com.qianwen.core.tool.utils.StringUtil; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.core.MethodParameter; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.lang.NonNull; @Aspect public class AuthAspect implements ApplicationContextAware { private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); private ApplicationContext applicationContext; public boolean doTenantFilter() { return AuthUtil.isAdministrator(); } @Around("@annotation(com.qianwen.core.secure.annotation.PreAuth) || @within(com.qianwen.core.secure.annotation.PreAuth)") public Object preAuth(ProceedingJoinPoint point) throws Throwable { if (doTenantFilter()) { return point.proceed(); } if (handleAuth(point)) { return point.proceed(); } throw new SecureException(ResultCode.API_UN_AUTHORIZED); } private boolean handleAuth(ProceedingJoinPoint point) { //MethodSignature ms = point.getSignature(); MethodSignature ms = (MethodSignature)point.getSignature(); Method method = ms.getMethod(); PreAuth preAuth = (PreAuth) ClassUtil.getAnnotation(method, PreAuth.class); String condition = preAuth.value(); if (StringUtil.isNotBlank(condition)) { Expression expression = EXPRESSION_PARSER.parseExpression(condition); Object[] args = point.getArgs(); StandardEvaluationContext context = getEvaluationContext(method, args); return ((Boolean) expression.getValue(context, Boolean.class)).booleanValue(); } return new AuthFun().hasApiPermission(); } private StandardEvaluationContext getEvaluationContext(Method method, Object[] args) { StandardEvaluationContext context = new StandardEvaluationContext(new AuthFun()); context.setBeanResolver(new BeanFactoryResolver(this.applicationContext)); for (int i = 0; i < args.length; i++) { MethodParameter methodParam = ClassUtil.getMethodParameter(method, i); context.setVariable(methodParam.getParameterName(), args[i]); } return context; } public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }