I have a controller with several endpoints. Every endpoint is mapped to a service which could return 200 or throw an exception, that is then handled and will return the correct error message.
For example, if a user is not found I throw a UserNotFoundException
, which is then caught in the ControllerAdvisor that maps it in a 404 not found.
Everything worked fine, until I added the @PreAuthorize. It looks like this:
@PreAuthorize("@userController.userService.getUser(#userId).username == authentication.principal.name")
The problem is that if getUser
throws an exception I get a 500 in place of a 404.
The stack trace looks like this:
java.lang.IllegalArgumentException: Failed to evaluate expression ‘@userController.userService.getUser(#userId).username == authentication.principal.name’
at …
Caused by: org.springframework.expression.ExpressionInvocationTargetException: A problem occurred when trying to execute method ‘getUser’ on object of type …
at …
Caused by: UserNotFoundException
So it looks like the problem is caused by the UserNotFoundException
, which is not properly re-thrown by the PreAuthorize
implementation.
This looks like a typical scenario, but I’ve researched a lot and I didn’t find any solution. How can I get my 404 when a user is not found?
Advertisement
Answer
There’s no added benefit of using @PreAuthorize
in this case.
Just throw your UserNotFoundException
within your business logic and map this exception to a 404
in your ControllerAdvisor
like you did before.