javaspringspring-securityaopspring-4

Ordering of Spring Security annotations


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();

Solution

  • 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.