使用shiro、自定义注解,加切面实现权限校验,注意使用@Around时,如果需要返回参数需要return ProceedingJoinPoint中的proceed对象 OBJ。案例如下
import org.apache.shiro.authz.annotation.Logical;
import java.lang.annotation.*;
/**
*
* @Description 权限注解
*
* @return null
* @Author jcl
* @Date 2024/7/9
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Permissions {
String value();
}
/**
* @program:
* @description:
* @author: jcl
* @create: 2024-07-09 10:54
**/
@Aspect
@Component
@Slf4j
public class PermissionsAspect {
// 使用 @annotation 指定要切入的注解
@Pointcut("@annotation(com.xx.xx.annotation.Permissions)")
public void permission() {
}
// 在方法返回后触发日志打印,并获取返回值
@Around("permission()")
public Object logAfterControllerMethods(ProceedingJoinPoint pjp) throws Throwable {
Subject subject = SecurityUtils.getSubject();
Signature signature = pjp.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
if (targetMethod.isAnnotationPresent(Permissions.class)) {
//获取方法上注解中表明的权限
Permissions permission = targetMethod.getAnnotation(Permissions.class);
//获取权限注解value,可能有多个
String permissionCode = permission.value();
boolean permitted = subject.isPermitted(permissionCode);
if (permitted) {
//这里不return那就拿不到值接口
return pjp.proceed();
} else {
throw new BusinessException(ResponseCodeConstant.ACCESS_DENIED, "没有权限,请确认您拥有此权限后尝试重新登录!");
}
} else {
throw new BusinessException(ResponseCodeConstant.ACCESS_DENIED, "权限注解校验失败,请联系管理员!");
}
}
}