将AccessDeniedException传播到Spring Security 3.2

时间:2015-09-04 16:39:49

标签: spring spring-mvc spring-security

我在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和子类并重写一个方法吗?

3 个答案:

答案 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());
  }