Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@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

like image 797
Andriy Kryvtsun Avatar asked Oct 23 '25 18:10

Andriy Kryvtsun


1 Answers

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.

like image 92
Kayaman Avatar answered Oct 26 '25 06:10

Kayaman