2015-09-04 2 views
1

Я использую глобальную защиту метода в Spring Security 3.2 и Spring 4.1.7 (Boot 1.2.5). Глобальные методы безопасности безопасности Spring перебрасывают AccessDeniedException. Однако у меня есть обработчик исключений, аннотированный с помощью @ControllerAdvice с методом ExceptionHandler, который ловит Exception, поэтому AccessDeniedException не распространяется до Spring Security ExceptionResolvingFilter; следовательно, он не обрабатывается Spring Security.Propagate AccessDeniedException to Spring Security 3.2

Я пробовал следовать советам here и создал еще один метод ExceptionHandler, который специально обрабатывает AccessDeniedException и просто пересказывает его. Но исключение снова не доходит до Spring Security; она проглатывается весны ExceptionHandlerExceptionResolver в строке 366:

// ============ 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; 
} 

Как я могу получить AccessDeniedException для распространения в Spring Security? Должен ли я создать пользовательский ExceptionResolver и подкласс и переписать этот метод?

ответ

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 класс я написал для структурирования й ответ.

Это работает, хотя я имитация обработки исключений весны ...

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; 
} 
+0

В этом проблема: это не мой код, это весна. 'ExceptionHandlerExceptionResolver', строка 366. –

0

Вы также можете сделать это, просто установив ошибку в объекте ответа, добавив следующий код в @ControllerAdvice классе.

@ExceptionHandler (value = {AccessDeniedException.class}) 
    public void commence(HttpServletRequest request, HttpServletResponse response, 
     AccessDeniedException accessDeniedException) throws IOException { 
    response.sendError(HttpStatus.FORBIDDEN, accessDeniedException.getMessage()); 
    } 
Смежные вопросы