Java 当@PostAuthorize失败时,返回404而不是403

Java 当@PostAuthorize失败时,返回404而不是403,java,spring,spring-security,Java,Spring,Spring Security,假设我有以下控制器。(假设Order.customer是订单所属的客户,只有他们才能访问该订单。) @RestController @请求映射(“/orders”) 公共类OrderController{ @GetMapping @PostAuthorize(“returnObject.customer==authentication.principal”) 公共订单getOrderById(长id){ /*查一下订单并退回*/ } } 在查找订单后,@PostAuthorize用于确保订单属

假设我有以下控制器。(假设
Order.customer
是订单所属的客户,只有他们才能访问该订单。)

@RestController
@请求映射(“/orders”)
公共类OrderController{
@GetMapping
@PostAuthorize(“returnObject.customer==authentication.principal”)
公共订单getOrderById(长id){
/*查一下订单并退回*/
}
}
在查找订单后,
@PostAuthorize
用于确保订单属于经过身份验证的客户。否则,弹簧将以403禁止响应

这样的实现有一个问题:客户端可以区分不存在的订单和无法访问的订单。理想情况下,在这两种情况下都应该返回404


虽然这可以通过将
身份验证
注入处理程序方法并在其中实现自定义逻辑来解决,但有没有办法使用
@PostAuthorize
或类似的声明性API来实现这一点?

您可以尝试使用ControllerAdvice捕获并转换AccessDeniedException,这是PostAuthorize抛出的

@RestControllerAdvice
public class ExceptionHandlerController {

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(AccessDeniedException.class)
    public String handleAccessDenied(AccessDeniedException e) {
        return "nothing here"; // or a proper object
    }
}

您可以尝试使用ControllerAdvice捕获并转换后授权抛出的AccessDeniedException

@RestControllerAdvice
public class ExceptionHandlerController {

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(AccessDeniedException.class)
    public String handleAccessDenied(AccessDeniedException e) {
        return "nothing here"; // or a proper object
    }
}

您可以在Spring安全配置中指定自定义的
AccessDeniedHandler

在下面的示例中,处理程序将返回一个404 Not Found on access denied failure

@EnableWebSecurity
公共类SecurityConfig扩展了WebSecurity配置适配器{
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http
// ...
.异常处理(异常处理->异常处理
.accessDeniedHandler(accessDeniedHandler())
);
}
@豆子
公共AccessDeniedHandler AccessDeniedHandler(){
返回新的CustomAccessDeniedHandler();
}
}
公共类CustomAccessDeniedHandler实现AccessDeniedHandler{
@凌驾
公共无效句柄(HttpServletRequest请求、HttpServletResponse响应、AccessDeniedException AccessDeniedException)引发IOException{
response.sendError(HttpStatus.NOT_FOUND.value(),HttpStatus.NOT_FOUND.getReasonPhrase());
}
}

您可以在Spring安全配置中指定自定义的
AccessDeniedHandler

在下面的示例中,处理程序将返回一个404 Not Found on access denied failure

@EnableWebSecurity
公共类SecurityConfig扩展了WebSecurity配置适配器{
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http
// ...
.异常处理(异常处理->异常处理
.accessDeniedHandler(accessDeniedHandler())
);
}
@豆子
公共AccessDeniedHandler AccessDeniedHandler(){
返回新的CustomAccessDeniedHandler();
}
}
公共类CustomAccessDeniedHandler实现AccessDeniedHandler{
@凌驾
公共无效句柄(HttpServletRequest请求、HttpServletResponse响应、AccessDeniedException AccessDeniedException)引发IOException{
response.sendError(HttpStatus.NOT_FOUND.value(),HttpStatus.NOT_FOUND.getReasonPhrase());
}
}