Affect all branch
Describe the bug
The exception handler method defined in the Controller is intercepted by the security annotation
To Reproduce see Sample code
Expected behavior
The exception handler method handleException can be executed
Sample
Comment From: marcusdacoregio
Hi @kse-music.
Have you verified if the problem persists in the latest version? Looks like it has been fixed via https://github.com/spring-projects/spring-security/issues/15352
Comment From: kse-music
@marcusdacoregio The latest version still exists
Comment From: kse-music
Hi @kse-music.
Have you verified if the problem persists in the latest version? Looks like it has been fixed via #15352
In addition, I think this is a common problem, because after the BeanPostProcessor (AbstractAutoProxyCreator)generates the proxy object, subsequent executions of the methods in the object are based on the proxy object, so they will be intercepted. As more, if the object SmartInitializingSingletoninterface is implemented, during execution afterSingletonsInstantiated also be intercepted when app is starting .This leads to a direct startup failure.
I'm not sure if I need to add a mechanism to exclude the methods of spring internal interfaces, such as ApplicationListener SmartLifecycle etc.
Comment From: jzheaux
While I'm interested in continuing this conversation, I'm not sure how much effort we should put into skipping certain methods when a class-level annotation is in place. Ostensibly, placing @PreAuthorize on a class means "please pre-authorize all the methods declared in this class".
The better solution, I believe, is to instead place the annotation on a parent interface that more clearly indicates which methods or to place the annotation directly on the methods that need authorization.
The technique outlined here may also be of interest.
For my reference, can you please produce a sample that uses a Spring Security version where the above application works as you expect?
Comment From: kse-music
I have added sample code
While I'm interested in continuing this conversation, I'm not sure how much effort we should put into skipping certain methods when a class-level annotation is in place. Ostensibly, placing
@PreAuthorizeon a class means "please pre-authorize all the methods declared in this class".
I agree, but technically it does exist.In my sample code: 1. curl http://127.0.0.1:8080/user/getName it doesn't execute handleException method 2. When opening the comment code in PostRestApi, the DemoApplication startup failure
The better solution, I believe, is to instead place the annotation on a parent interface that more clearly indicates which methods or to place the annotation directly on the methods that need authorization. The technique outlined here may also be of interest.
The fix here solves gh-15352, but also causes gh-13783 to fail, even in 6.4.0-M3. I copied the code in gh-13783 to the gh13789 package of the sample code:
curl http://127.0.0.1:8080/hello it doesn't execute @PreAuthorize method
Comment From: jzheaux
I hear your concerns, @kse-music. Since it seems your most recent comments are about how Spring Security searches hierarchically for annotations, let's continue chatting about that at #15352 so that the conversation doesn't become fragmented.
In addition, I think this is a common problem, because after the BeanPostProcessor (AbstractAutoProxyCreator )generates the proxy object, subsequent executions of the methods in the object are based on the proxy object, so they will be intercepted. As more, if the object SmartInitializingSingleton interface is implemented, during execution afterSingletonsInstantiated also be intercepted when app is starting .This leads to a direct startup failure.
Your point here is well-taken though I don't know how we can provide a complete solution to avoid all the methods that folks might want to skip. Better, I think is to either publish a technique or to make the default configuration simple to alter.
For example, if an application is determined to use @PreAuthorize on a concrete class that contains methods it doesn't want that annotation to apply to, applications can craft their own pointcut as follows:
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static AuthorizationAdvisor preAuthorizeAuthorizationAdvisor() {
AuthorizationManagerBeforeMethodInterceptor preAuthorize =
AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
Pointcut hasPreAuthorizeAnnotation = preAuthorize.getPointcut();
String expression = "!@annotation(org.springframework.web.bind.annotation.ExceptionHandler)";
Pointcut skipExceptionHandler = new AspectJPointcutExpression(expression);
preAuthorize.setPointcut(Pointcuts.intersection(hasPreAuthorizeAnnotation, skipExceptionHandler));
return preAuthorize;
}