Describe the bug If I use class-level annotation @PreAuthorize it's going to be ignored for methods from the parent class if they are not overridden

To Reproduce With this code call to findAll is not secured

public abstract class AbstractResource {

       @GetMapping
       public Entity findAll(String param) {
                return new Entity();
       }
}

@PreAuthorize("hasAuthority('ENTITY_READ')")
@RequestMapping("/enitity")
@Controller
public class SomeResource extends AbstractResource {
}

In logs I see something like that

2023-10-26T19:52:10.634+02:00 DEBUG 24308 --- [nio-8080-exec-9] horizationManagerBeforeMethodInterceptor : Authorizing method invocation ReflectiveMethodInvocation: public org.springframework.data.domain.Page com.some.resources.AbstractResource.findAll(java.util.Optional); target is of class [com.some.resources.EntityResource]

If I override it in the child class all works as expected.

Expected behavior Methods from parent classes shall also be secured by @PreAuthorize on child class.

Sample

A link to a GitHub repository with a minimal, reproducible sample.

Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.

Comment From: usharik

Not needed

Comment From: marcusdacoregio

Hi, @usharik. Thanks for the report.

What do you mean by Not needed?

Comment From: usharik

I'm sure that this bug is not going to be implemented because it could be against the Spring Security architecture. Method secure annotations are about only method in current class and not about methods from parent class.

Please fix me if I'm wrong

Comment From: marcusdacoregio

I tried it myself and the method security worked, see https://github.com/marcusdacoregio/spring-security-examples/blob/gh-14053/src/main/java/com/example/springsecurityexamples/SpringSecurityExamplesApplication.java. You can run the application and do a GET :8080/ -a user:password.

I'll close this since it works, but if you still think that this is a bug or there is a scenario where it doesn't work, please provide a minimal, reproducible sample then we can reopen this issue.

Comment From: usharik

@marcusdacoregio there is some difference between your example and mine. You have security annotation in the abstract class but I have it in the inherited class. The idea of my code that basic abstract resource class is used as parent for different entities resource classes which could be secure differently.

Comment From: marcusdacoregio

Hi, @usharik. You can provide a minimal, reproducible sample by using the code that I shared above. That would help us to see better what your configuration looks like.

Comment From: befresh-mweimerskirch

I'm having the (I think) same issue.

Here's a minimal reproducible example:

package com.example.springsecurityexamples;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class SpringSecurityExamplesApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurityExamplesApplication.class, args);
    }

    @RestController
    @PreAuthorize("hasRole('ADMIN')")
    class Controller extends Resource {


    }

    abstract class Resource {

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

    }

}

My use case is to have an abstract parent "AdminController" and child classes for different resource types (e.g. a CategoryAdminController would extend AdminController). For each resource type the required roles are different, which is why I wanted to put the PreAuthorize annotation on the child classes rather than on the abstract parent class (e.g. a ROLE_CATEGORY_ADMIN) on the CategoryAdminController.

But like @usharik wrote this might be intended. Can you confirm this is not a bug? Because I found it counterintuitive.