我在Spring Security 3.2和Spring 4.1.7(Boot 1.2.5)中使用全局方法安全性。 Spring的全局方法安全拦截器抛出AccessDeniedException
。但是,我有一个带有@ControllerAdvice
注释的异常处理程序,其ExceptionHandler
方法捕获Exception
,因此AccessDeniedException不会传播到Spring Security ExceptionResolvingFilter
;因此,它不是由Spring Security处理的。
我尝试按照建议here创建另一个专门处理ExceptionHandler
的{{1}}方法并简单地重新抛出它。但是这个例外再也没有达到Spring Security的要求;春天的AccessDeniedException
在第366行吞下了它:
ExceptionHandlerExceptionResolver
如何让// ============ SPRING'S EXCEPTIONHANDLEREXCEPTIONRESOLVER CODE ==========
try {
if (logger.isDebugEnabled()) {
logger.debug("Invoking @ExceptionHandler method: " + exceptionHandlerMethod);
}
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception);
}
catch (Exception invocationEx) {
if (logger.isErrorEnabled()) {
logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
}
return null;
}
传播到Spring Security?我必须创建自定义AccessDeniedException
和子类并重写一个方法吗?
答案 0 :(得分:0)
您的代码吞噬了异常
catch (Exception invocationEx) {
if (logger.isErrorEnabled()) {
logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
}
return null; // here is the culprit
}
记录它或重新抛出它会很好
catch (Exception invocationEx) {
if (logger.isErrorEnabled()) {
logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
}
throw invocationEx;
}
答案 1 :(得分:0)
最后,我要做的是向@ControllerAdvice
类添加一个方法:
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<WebServiceResponse> handleAccessDeniedException(AccessDeniedException ex)
{
WebServiceResponse response = new WebServiceResponseWithError(status: 'failure', message: ex.message, errorCode: 1007)
return new ResponseEntity(response, HttpStatus.FORBIDDEN)
}
WebServiceResponse
是我为构建响应而编写的一个类。
虽然我模仿了Spring的异常处理......但是这很有效。
答案 2 :(得分:0)
您也可以通过在@ControllerAdvice
类中添加以下代码来设置响应对象中的错误。
@ExceptionHandler (value = {AccessDeniedException.class})
public void commence(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
response.sendError(HttpStatus.FORBIDDEN, accessDeniedException.getMessage());
}