Search code examples
javaspringspring-securityannotations

@PreAuthorize annotations combining


I use several @PreAuthorize-base annotations for protecting my REST API methods.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public @interface ForAorB {
}

and at the same time I have

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ROLE_A')")
public @interface ForA {
}

and

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ROLE_B')")
public @interface ForB {
}

My @PreAuthorize expressions are a bit more complex than simple hasRole('ROLE_x) and I would like not to doubling them both in @ForA, @ForB and in @ForAorB.

Whether it possible to create @ForAorB annotation bases on @ForA and @ForB and not expressions doubling in @PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")?

I tried this but looks like

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@ForA @ForB
public @interface ForAorB {
}

works actually as @ForAandB but not @ForAorB


Solution

  • That won't work, because annotations (at least in this case) are "additive". A single @PreAuthorize annotation will give you OK or NOK, and that determines the whole outcome regardless of any other possible auth annotations.

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @ForA @ForB
    public @interface ForAorB {
    }
    

    is the same as

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @PreAuthorize("hasRole('ROLE_A')")
    @PreAuthorize("hasRole('ROLE_B')")
    public @interface ForAorB {
    }
    

    So for AND it works, but you can't get it to work with OR except writing the @PreAuthorize annotation by hand.