二十七、权限控制的自定义注解实现方式

来源:互联网 发布:汤姆索亚历险记 知乎 编辑:程序博客网 时间:2024/05/01 05:23

目的:将账号的操作权限通过数据库进行配置,程序限制只有当拥有某权限时才能调用相应方法。

首先在注解类里定义权限(包括读、写、审核权限)。

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface AuthAnnotation {public enum AuthLevel{read,write,examine}public AuthLevel value();}

然后是对上面注解类进行解析的类:

@Componentpublic class AnnotationParse {    @Autowiredprivate TmallAuthDAO tmallAuthDAO;    public void parseMethod(Class clazz,long userId, long operateObj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, InstantiationException{           Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[]{});           for(Method method : clazz.getDeclaredMethods()){           AuthAnnotation authAnnotation = method.getAnnotation(AuthAnnotation.class);              if(authAnnotation != null){              TmallAuthDO tmallAuthDO =  (TmallAuthDO) tmallAuthDAO.getAuthByUserIdAndOperateObj(userId, operateObj);          if(tmallAuthDO != null){        long needCheckedAuth = authAnnotation.value()==AuthLevel.read?1:authAnnotation.value()==AuthLevel.write?2:authAnnotation.value()==AuthLevel.examine?4:null;      if((tmallAuthDO.getOperate() & needCheckedAuth) == needCheckedAuth){      method.invoke(obj, authAnnotation.value());      }else{      }      }          }           }      }  } 

注:tmallAuthDO.getOperate()中存储的是userId对operateObj这条数据记录的操作权限,会将权限与注解限制的条件(即下面注解方法的@AuthAnnotation(AuthLevel.read)中的AuthLevel.read)进行按位与,这样一个账号对某条数据可以拥有多个权限,相应权限控制的多个方法才能都执行。

定义好了,下面就是使用了:

public class UserAuthInfo {@AuthAnnotation(AuthLevel.examine)public void check(AuthLevel authLevel){System.out.println("哈哈,可以进行审批工作");}@AuthAnnotation(AuthLevel.read)public void read(AuthLevel authLevel){System.out.println("哈哈,可以进行查阅工作");}@AuthAnnotation(AuthLevel.write)public void write(AuthLevel authLevel){System.out.println("哈哈,可以进行录入、修改工作");}}

客户端调用的方式:

@Componentpublic class AuthInvoker {@Autowiredprivate AnnotationParse annotationParse;public void methoda(long userId, long operateObj) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{annotationParse.parseMethod(UserAuthInfo.class,userId,operateObj);}}

单元测试的方法:

@Test

@Testpublic void testAuth() throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{authInvoker.methoda(2030802211, 2);}

 

数据准备:首先建这样一张表


插入一条数据,让会员id为2030802211,赋予权限operate=5(读1、审核4)。

执行的结果如下:

可以看到,读权限的方法read和审核权限的方法check都被执行了,而有写权限才能执行的方法write并没有被执行,这正是想要的结果。


原创粉丝点击