目的:将账号的操作权限通过数据库进行配置,程序限制只有当拥有某权限时才能调用相应方法。
首先在注解类里定义权限(包括读、写、审核权限)。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AuthAnnotation { public enum AuthLevel{read,write,examine} public AuthLevel value(); }
然后是对上面注解类进行解析的类:
@Component public class AnnotationParse { @Autowired private 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("哈哈,可以进行录入、修改工作"); } }
客户端调用的方式:
@Component public class AuthInvoker { @Autowired private AnnotationParse annotationParse; public void methoda(long userId, long operateObj) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ annotationParse.parseMethod(UserAuthInfo.class,userId,operateObj); } }
单元测试的方法:
@Test
@Test public void testAuth() throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ authInvoker.methoda(2030802211, 2); }
数据准备:首先建这样一张表
插入一条数据,让会员id为2030802211,赋予权限operate=5(读1、审核4)。
执行的结果如下:
可以看到,读权限的方法read和审核权限的方法check都被执行了,而有写权限才能执行的方法write并没有被执行,这正是想要的结果。