java – Spring Security – 忽略@ExceptionHandler的Ajax调用

我的项目中有一个控制器,它处理所有定义的异常,如下所示:

@ControllerAdvice
public class GlobalExceptionHandlingController {

    @ResponseBody
    @ExceptionHandler(value = AccessDeniedException.class)
    public ResponseEntity accessDeniedException() {
        Logger.getLogger("#").log(Level.SEVERE, "Exception caught!");
        return new ResponseEntity("Access is denied", HttpStatus.FORBIDDEN);
    }

}

我在这里专注于一个特定的异常,那就是Spring Security对未经授权的请求抛出的AccessDeniedException.这适用于“普通”又称非ajax请求.我可以点击链接或直接在位置栏中输入网址,如果请求未经授权,我会看到此消息.

但是在AJAX请求上(使用Angular)我得到标准403错误页面作为响应,但有趣的是我可以看到AccessDeniedException被这个控制器捕获!

我做了一些研究,似乎我需要自定义AccessDeniedHandler,所以我做了这个:

在我的Spring Security配置中添加了以下行:

.and()
.exceptionHandling().accessDeniedPage("/error/403/");

我做了一个特殊的控制器只是为了处理这个:

@Controller
public class AjaxErrorController {

    @ResponseBody
    @RequestMapping(value = "/error/403/", method = RequestMethod.GET)
    public ResponseEntity accessDeniedException() {
        return new ResponseEntity("Access is denied (AJAX)", HttpStatus.FORBIDDEN);
    }

}

现在这工作正常,但异常仍然在第一个控制器中被捕获,但该方法的返回值被忽略.为什么?

这是应该怎么做的?我有一种感觉,我在这里遗漏了一些东西.

我在Spring Security 4.0.4中使用Spring 4.2.5.

最佳答案 虽然我不知道所有细节,但我的理论是它可能是一个内容类型问题.

通常在执行AJAX请求时,响应应该是JSON,因此浏览器会在请求中添加Accept:application / json标头.

另一方面,您的回复实体:

new ResponseEntity("Access is denied", HttpStatus.FORBIDDEN)

是一个文本响应,默认的Content-Type与典型的Spring设置是text / plain.

当Spring检测到它无法提供客户端所需类型的响应时,它将回退到默认错误页面.

点赞