目的:将账号的操作权限通过数据库进行配置,程序限制只有当拥有某权限时才能调用相应方法。
首先在注解类里定义权限(包括读、写、审核权限)。
@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并没有被执行,这正是想要的结果。