DEV Community

Luciano Pinheiro
Luciano Pinheiro

Posted on

Custom annotation to check authorization in Spring

In Spring, we have the ability to apply custom annotations to methods, classes, or fields, in order to execute specific actions before or after the annotated object. This is achieved through Aspect-Oriented Programming (AOP).

To implement this solution, we need to create both a custom annotation and a method that will be triggered when the application encounters the annotation. Annotations serve as markers, indicating a specific point in the code, and in order to perform an action, we need to associate that marker with a method from a designated class. Therefore, creating a custom annotation also involves creating an Aspect class/method.

For example, let's consider an annotation that verifies if a person has a particular role. This annotation can be used within methods in a Spring Controller.

Annotation @VerifyAuthorization

To create an annotation, you need to use the syntax below. Please notice:

  • Use @interface to define the annotation
  • Use @Retention to choose the policy (usually RUNTIME)
  • Use @Target to specify the element type (TYPE for class, METHOD, or FIELD)

To create an annotation with parameters, we need to define them as the syntax below.


// define annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) 
public @interface VerifyAuthorization {
    String value() default "";
}

// use in a controller method
@RestController
public class ThisController {
    @VerifyAuthorization 
    public String save () {...}
}

Enter fullscreen mode Exit fullscreen mode

Aspect Method

With Aspect, we can intercept virtually any call in Java. There are two frameworks for this: Spring AOP and AspectJ. While AspectJ is more flexible, it is also more complex.

To intercept the annotation and execute a specific method before (or after or around) the annotated target, we define what is called advice.

Firstly, we need to install spring-boot-starter-aop if using Spring Boot or AOP and AspectJ if using Spring. There is a trick. AspectJ doesn't search targets automatically. So, we need to enable this feature in a XML or annotation format.

After all installations and configurations are completed, we can create a method and link it to the annotation.

Notice in the syntax:

  • @Aspect annotation for the aspect class
  • @Component to make it unique
  • @Before (or @After or @Around) annotation indicating the annotation
  • JoinPoint holds the method information

Inside the method, we use some objects to access the annotated method and its parameters.

@Aspect
@Component
public class VerifyAuthorizationAdvice {

    @Before("@annotation(com.example.VerifyAuthorization)") 
    public void beforeAnnotation(JoinPoint joinPoint){
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        VerifyAuthorization annotation = signature.getMethod().getAnnotation(VerifyAuthorization.class);
        CustomUserSecurity.hasRole(annotation.value());
    }
}
Enter fullscreen mode Exit fullscreen mode

The VerifyAuthorizationAdvice class can include any necessary logic or dependency. In the example, @Before is used to run the method before the annotated one. If an exception is thrown, the original method will not be executed. Alternativelly, @After could be used to run it after the original method, or @Around to replace it. When using @Around, we can control when the original method is executed by calling joinPoint.proceed(); at some point within our advice method.

Top comments (0)