We should look into how to provide native hints for bean methods used inside Method Security annotations.

Currently, in order to make this work:

@Component
class Authz {
   boolean check(Authentication authentication, String id, String permission) {
      return "admin".equals(authentication.getName());
   }
}

@PreAuthorize("@authz.check(authentication, #id, 'read')")
String findById(String id) {

}

We need to register hints:

@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
    hints.reflection().registerType(Authz.class, MemberCategory.INVOKE_DECLARED_METHODS);
}

Related to - https://github.com/spring-projects/spring-framework/issues/29548

Comment From: marcusdacoregio

@sbrannen provided some insights on how we could achieve that:

  • Parse the SpEL expression and then walk the AST to find nodes of type BeanReference and then retrieve the beanName from that.
  • beanName is a private field with no getter, we can probably use reflection or parse the bean name from the string returned from toStringAST().
  • Once we know the beanName we can look up that bean in the ApplicationContext and register hints for the bean's concrete type.

Comment From: sbrannen

beanName is a private field with no getter, we can probably use reflection or parse the bean name from the string returned from toStringAST().

Please note that BeanReference will have a getName() method in Spring Framework 6.2.

If it's needed in 6.1.x, we could consider backporting it.

  • See https://github.com/spring-projects/spring-framework/issues/32640