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

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

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

@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)。

二十七、权限控制的自定义注解实现方式_第1张图片

执行的结果如下:

二十七、权限控制的自定义注解实现方式_第2张图片

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


你可能感兴趣的:(二十七、权限控制的自定义注解实现方式)