Java Spring : how can I encapsulate annotations within an other annotation?

Is it possible to encapsulate an annotation within an other annotation with values?

I have a lot of end points on my API and would like to automate the required roles / permissions for the end point access.

Here is the current code :

@RestController
@RequestMapping("/health")
public class HealthController {
    @GetMapping("/isAlive")
    @PreAuthorize("hasAnyAuthority('ISALIVE', 'HEALTH_ENDPOINT')")
    public String isAlive() {
        return "Server is up and running";
    }

    @GetMapping("/hello")
    @PreAuthorize("hasAnyAuthority('HELLO', 'HEALTH_ENDPOINT')")
    public String hello() {
        return "Hello";
    }
}

I have 2 authorities per end point, the first is the name of the mapping and method and the second is the name of the class.

In this example there is only 2 different end points with makes it easy but the finished product will have in the hundreds and doing all of the authorities by hand is going to be error-prone and not very efficient.

This is the desired result :

@RestController
@RequestMapping("/health")
public class HealthController {
    @GetMapping("/isAlive")
    @MyAuthorisationAnnotation
    public String isAlive() {
        return "Server is up and running";
    }

    @GetMapping("/hello")
    @MyAuthorisationAnnotation
    public String hello() {
        return "Hello";
    }
}

Where @MyAuthorisationAnnotation would give the right parameters to the @PreAuthorize annotation.

Is it possible?

1 answer

  • answered 2021-04-22 06:44 Sergio

    Is it possible to encapsulate an annotation within an other annotation with values?

    An annotation can have another annotation as a member.

    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAuthorizationAnnotation {
       PreAuthorize value() default @PreAuthorize("hasAnyAuthority('HELLO', 'HEALTH_ENDPOINT')"); 
    }
    

    However I don't think this helps. I am not familiar with Spring, but I think this post solves your problem, because it seems that @PreAuthorize can be applied to annotations so you can leverage transitivity if you use the checked annotation in a method.

    Solution's Post