Talking about a simple annotation of authority control based on SpringBoot

  • 2021-08-12 02:45:12
  • OfStack

Annotation is an annotation mechanism introduced in JDK 5.0. Annotations can be used in different locations of types (classes, interfaces, enumerations, etc.), properties, methods, parameters, etc. For specific annotation locations supported by JDK version, please refer to java. lang. annotation. ElementType. In addition, there is an annotated strategy, that is, RetentionPolicy, which will not be repeated here.

Annotations can achieve many functions, the most important of which is to annotate code, so sometimes annotations are also called annotations. It is basically just as its name implies, that is, it annotates the code and simplifies the logic of some codes.

Let's begin to implement a simple permission control annotation to have a basic understanding of annotations.

Prepare

@ Permission notes

The code for the annotation itself is simple. The following implementation is a @ Permission annotation. For convenience, only one attribute value is provided here, because if there is one attribute named value in one annotation and you only want to set the value attribute (that is, all other attributes adopt default values or you only have one value attribute), you can omit the "value=" section.


import java.lang.annotation.*;

@Target({ElementType.PARAMETER}) //  Annotations can be used for parameters 
@Retention(RetentionPolicy.RUNTIME) //  Annotations are available at run time by the JVM Read in 
@Documented
public @interface Permission {
  String value() default "";
}

Class User

A simple User class containing permissions for holding user permissions.


import lombok.Data;

@Data
public class User {
  private String id;
  private String name;

  private Set<String> permissions;
}

Class UserService

Simple Service class for judging permissions.


@Service
public class UserService {
  public boolean checkCreatePermission(@Permission(" Create a user ") User user) {
    return true;
  }

  public boolean checkDeletePermission(@Permission(" Delete user ") User user) {
    return true;
  }
}

Class PermissionAspect

Use SpringBoot to simply set the section, get comments and use. Direct here


@Aspect
@Component
public class PermissionAspect {
  //  Need to be modified to actual  Service  In  Package
  @Pointcut("execution(public * tk.yubarimelon.MongoDemo.service.*.*(..))") 
  public void permissionCheck() {
  }

  @Around("permissionCheck()")
  public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
    Object[] params = joinPoint.getArgs();
    //  Gets the method where you can set the signature Forced conversion MethodSignature
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();

    //  Get parameter comments, 1 Dimensions are parameters, 2 Dimension is annotation 
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    for (int i = 0; i < parameterAnnotations.length; i++) {
      Object param = params[i];
      Annotation[] annotations = parameterAnnotations[i];
      if (!(param instanceof User) || annotations.length == 0) {
        continue;
      }
      for (Annotation annotation : annotations) {
        if (annotation.annotationType().equals(Permission.class)) {
          Permission permission = (Permission) annotation;
          User user = (User) param;
          if (CollectionUtils.isEmpty(user.getPermissions())) {
            log.error(user.getName() + "  No permission! ");
            return false;
          }
          if (!StringUtils.hasLength(permission.value())) {
            log.error(joinPoint.getSignature().toString() + " Exception of permission setting ");
            return false;
          }
          if (!user.getPermissions().contains(permission.value())) {
            log.error(joinPoint.getSignature().toString() +": "+user.getName() + "  No authority : " + permission.value());
            return false;
          }
          return joinPoint.proceed();
        }
      }
    }
    return joinPoint.proceed();
  }
}

Class ApplicationTests

Simple test class for testing code. Here, simply configure 1 user to only have the permission to create users


@SpringBootTest
class ApplicationTests {

  @Autowired
  UserService userService;

  @Test
  void contextLoads() {
  }

  @Test
  void checkUser() {
    User user = new User();
    user.setName(" Xiao Ming ");
    Set<String> permissions = new HashSet<>();
    permissions.add(" Create a user ");
    user.setPermissions(permissions);

    System.out.println("checkCreatePermission " + userService.checkCreatePermission(user));
    System.out.println("checkDeletePermission " + userService.checkDeletePermission(user));
  }
}

Output the following log to prove that the permission setting works.

checkCreatePermission true
2021-01-31 11:44:45. 895 ERROR 12388--[main] t. y. MongoDemo. aop: boolean tk. MongoDemo. service. UserService. checkDeletePermission (User): Xiaoming No Permission: Delete User
checkDeletePermission false


Related articles: