When you annotating method A with @Pre/PostAuthorize
than spring will create proxy for such object and each call to such method will go through proxy (if object is under spring context).
The proxy for @Pre/PostAuthorize
will evaluate expression from annotation (complicated here) and if it's true than pass the request father (to real method) if not than throw AccessDaniedException. You can also throw such exception by yourself in your method A and the effect will be the same. It's all about how @Pre/PostAuthorize
works no more magic here!
But it's not the end of the story!
If AccessDaniedException
is not suppressed or retranslated (without stack which doesn't have AccessDaniedException
) than it will be catched by ExceptionTranslationFilter
in Spring Security and ExceptionTranslationFilter
will see if user is Authenticated
if yes than ExceptionTranslationFilter
will delegate to AccessDeniedHandler
to deal with the situation and default implementation of AccessDeniedHandler
will return 403 http code or redirect to error page depends if you are using rest or not.
if not, than ExceptionTranslationFilter
will delegate to AuthenticationEntryPoint
and it will deal with the situation (redirect to login page, ask for http basic ... etc).
Note: ExceptionTranslationFilter
will rethrow exception if any other than AuthenticationException
or AccessDeniedException
and probably 500 will be shown :(
Your problem is probably another problem look at Spring Security anonymous 401 instead of 403
Suppressed :(:
@GetMapping(value = "/test/ok")
public String getOk() {
try {
myService.securedMethod();
return "ok";
} catch (Exception e) {
log.info("AccessDeniedException suppressed not rethrowing :(", e);
return "error";
}
}
Correct retranslated :) :
@GetMapping(value = "/test/ok")
public String getOk() {
try {
myService.securedMethod();
return "ok";
} catch (AccessDeniedException e) {
throw new MyException(e); //public MyException(Throwable cause)
}
}