If a method has multiple security annotations, in what order are they applied?
For example, is it the order in which the annotations are defined, or is it fixed such that e.g. SecuredAnnotationSecurityMetadataSource
is always used before PrePostAnnotationSecurityMetadataSource
?
Put another way, what is the evaluation order when calling these methods?
@Secured("ROLE_ADMIN")
@PreAuthorize("hasPermission(#target, 'read')")
void method1();
@PreAuthorize("hasPermission(#target, 'read')")
@Secured("ROLE_ADMIN")
void method2();
@PreAuthorize("hasRole('ADMIN') && hasPermission(#target, 'read')")
void method3();
@PreAuthorize("hasPermission(#target, 'read') && hasRole('ADMIN')")
void method4();
tl;dr: Mixing @Secured
and @PreAuthorize
does not work.
As detailed here, the method security interceptor stops once it has found the first supported annotation.
for (MethodSecurityMetadataSource s : methodSecurityMetadataSources) {
attributes = s.getAttributes(method, targetClass);
if (attributes != null && !attributes.isEmpty()) {
break;
}
}
it's intentional that
DelegatingMethodSecurityMetadataSource
only uses one source of metadata, the first which returns a non-null result
The ordering is @PreAuthorize
≻ @Secured
≻ @RolesAllowed
. Therefore methods one and two in the question are actually equivalent to
@PreAuthorize("hasPermission(#target, 'read')")
void method();
i.e. the @Secured
annotation is silently ignored.