1. 添加pom支持
<!-- 引入aop切面支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 添加注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface AuthPermission {
AuthResourceEnum authResourceCode();
AuthBusinessTypeEnum businessType() default AuthBusinessTypeEnum.DEFAULT_KEY;
String businessId() default "";
String userId() default "";
}
@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target –注解用于什么地方
@Inherited – 是否允许子类继承该注解
3. AOP接口类
public interface PermissionAop {
/**
* AOP接口
* @param: @param joinPoint
* @param: @throws Throwable
* @return: Object;
*/
Object permission(ProceedingJoinPoint joinPoint) throws Throwable;
}
4. 接口实现类,切点和注解绑定
@Aspect
@Component
public class PermissionAopImpl implements PermissionAop {
@Autowired
private PermissionAuthService permissionAuthService;
/**
* 定义注解类型的切点,只要方法上有该注解,都会匹配
*/
@Pointcut("@annotation(com.auth.AuthPermission)")
public void pointcut() {
}
@Value("${auth.checkAuth}")
private Boolean checkAuth;
/**
* AOP权限控制接口
*/
@Override
@Around("pointcut()")
public Object permission(ProceedingJoinPoint joinPoint) throws Throwable {
if(!checkAuth)
{
return joinPoint.proceed();
}
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
EvaluationContext context = new StandardEvaluationContext();
AuthPermission permission = null;
// 处理Permission注解的方法
if (method.isAnnotationPresent(AuthPermission.class)) {
Object[] args = joinPoint.getArgs();
String[] parameterNames = new DefaultParameterNameDiscoverer().getParameterNames(method);
if (parameterNames == null) {
return joinPoint.proceed();
}
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
permission = method.getAnnotation(AuthPermission.class);
}
if(permission != null && !isAuthorized(context, permission))
{
throw new BusinessException(BusinessErrorEnum.AUTH_CHECK_ERROR);
}
return joinPoint.proceed();
}
// 解析注解中的参数
public boolean isAuthorized(EvaluationContext context, AuthPermission permission) throws Throwable {
ExpressionParser parser = new SpelExpressionParser();
String userId = getUserId(context, permission, parser);
//获取businessType
String businessType = permission.businessType().getCode();
//获取资源code
String resourceCode = permission.authResourceCode().getCode();
}
private String getUserId(EvaluationContext context, AuthPermission permission, ExpressionParser parser) {
String userIdEL = permission.userId();
String userId = "";
if(StringUtils.isNotBlank(userIdEL))
{
Expression expressionUser = parser.parseExpression(userIdEL);
userId = getExpressionValue(expressionUser, context);
}
if(StringUtils.isEmpty(userId))
{
userId = Common.getUserId();
}
if(org.apache.commons.lang.StringUtils.isEmpty(userId))
{
throw new BusinessException(BusinessErrorEnum.AUTH_CHECK_ERROR);
}
return userId;
}
}
@Aspect注解使该类成为切面类