@PreAuthorize 停止传播安全检查评估期间抛出的异常

@PreAuthorize stops propagating exceptions thrown during evaluation of security checks

我有一个带有多个端点的控制器。每个端点都映射到一个可以 return 200 或抛出异常的服务,然后处理该服务并将 return 正确的错误消息。

例如,如果未找到用户,我会抛出一个 UserNotFoundException,然后它会被 ControllerAdvisor 捕获,并在 404 not found 中映射它。

一切正常,直到我添加了@PreAuthorize。它看起来像这样:

@PreAuthorize("@userController.userService.getUser(#userId).username == authentication.principal.name")

问题是,如果 getUser 抛出异常,我得到 500 而不是 404。

堆栈跟踪如下所示:

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

所以看起来问题是由 UserNotFoundException 引起的,PreAuthorize 实现没有正确地重新抛出它。

这看起来是一个典型的场景,但我研究了很多,但没有找到任何解决方案。找不到用户时如何获取我的 404?

在这种情况下使用 @PreAuthorize 没有任何额外好处。

只需将您的 UserNotFoundException 放入您的业务逻辑中,并将此异常映射到您的 ControllerAdvisor 中的 404,就像您之前所做的那样。