切面权限控制
前言:使用AOP统计日志,控制权限
1. 创建切面
/**
* @author wangjinliang.wjl
* @date 2018/10/18
**/
@Slf4j
@Aspect
@Component
public class SecMapPermissionAspect {
//
}
2. 创建主注解类
/**
* @author wangjinliang.wjl
* @date 2018/10/18
*/
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CheckPermission {
String value();
}
3. 创建权限枚举类(多种权限情况存在)
/**
* @author wangjinliang.wjl
* @date 2018/10/18
**/
public class PermissionConstants {
/**
* 普通用户
*/
public static final String PUBLIC_USER = "public_user";
/**
* 超级用户
*/
public static final String SUPER_USER = "super_user";
}
4. 控制权限
使用@Before在切入点开始处切入内容
使用@After在切入点结尾处切入内容
使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
/**
* @author wangjinliang.wjl
* @date 2018/10/18
**/
@Slf4j
@Aspect
@Component
public class SecMapPermissionAspect {
//
@Around("@annotation(com.xxx.CheckPermission) || "
+ "@within(com.xxx.CheckPermission)")
public Object checkPermissions(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//获得请求参数
TestDeptQueryParam param = getTestParam(proceedingJoinPoint.getArgs());
Set<Permission> permissions = new HashSet<>();
//得到方法上的注解
MethodSignature methodSignature = (MethodSignature)proceedingJoinPoint.getSignature();
Method method = methodSignature.getMethod();
CheckPermission methodCheckPermission = method.getAnnotation(CheckPermission.class);
if(null != methodCheckPermission){
Collections.addAll(permissions, methodPermissions);
}
//得到类上的注解
CheckPermission classPheckPermission = proceedingJoinPoint.getTarget().getClass().getAnnotation(CheckPermission.class);
if(null != methodCheckPermission){
Collections.addAll(permissions, methodPermissions);
}
//依次检查权限
List<CHECK_PERMISSION_RESULT> permissionList = permissions.stream
.filter(Objects::nonNull)
.map(this::doCheckPermission);
//判断
if(permissionList.contains(CHECK_PERMISSION_RESULT.FORBIDDEN)){
return HttpResult(HttpStatusCode.NOPERMISSION,"无权限",param)
}else{
return proceedingJoinPoint.proceed();
}
}
private TestParam getTestParam(Object[] args) {
for (Object arg : args) {
if (arg instanceof TestDeptQueryParam) {
TestDeptQueryParam testDeptQueryParam = (TestDeptQueryParam)arg;
return testDeptQueryParam;
} else if (arg instanceof TestUserQueryParam) {
TestUserQueryParam testUserQueryParam = (TestUserQueryParam)arg;
TestDeptQueryParam testUserQueryParam = TestDeptQueryParam.builder()
.deptId(TestUserQueryParam.getId())
.build();
return secMapDeptQueryParam;
}
}
throw new RuntimeException("Check permission for SecMap, but not find SecMap param argument");
}
public enum CHECK_PERMISSION_RESULT {
// 有权限
PASS,
// 无权限
FORBIDDEN
}
}
具体的权限检验逻辑根据不同的业务逻辑进行修改