Pracuję nad usługą REST. Używa JSON i musi zwrócić jakiś predefiniowany obiekt JSON w przypadku problemów. Odpowiedź domyślna Wiosna wygląda następująco:Spring MVC (lub Spring Boot). Niestandardowa odpowiedź JSON dla wyjątków związanych z bezpieczeństwem, takich jak 401 Nieautoryzowane lub 403 Niedozwolone)
{
"timestamp": 1512578593776,
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/swagger-ui.html"
}
chcę zastąpić to ustawienie domyślne JSON z własnym jednego (z stacktrace i dodatkowe informacje dotyczące wyjątków).
Wiosna zapewnia wygodny sposób nadpisywania domyślnego zachowania. Należy zdefiniować komponent bean @RestControllerAdvice
za pomocą niestandardowej procedury obsługi wyjątku. Podoba Ci się to
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<ExceptionResponse> unknownException(Exception ex) {
ExceptionResponse resp = new ExceptionResponse(ex, level); // my custom response object
return new ResponseEntity<ExceptionResponse>(resp, resp.getStatus());
}
@ExceptionHandler(value = {AuthenticationException.class})
public ResponseEntity<ExceptionResponse> authenticationException(AuthenticationExceptionex) {
// WON'T WORK
}
}
Zwyczaj ExceptionResponse
obiekt zostanie następnie konwertowane do formatu JSON do wiosny pomocą specjalnego konwertera wiadomość.
PROBLEM JEST, że wyjątki takie jak InsufficientAuthenticationException
bezpieczeństwa nie mogą zostać przechwycone przez sposób adnotacją @ExceptionHandler
. Ten rodzaj wyjątków ma miejsce przed wprowadzeniem serwletu dyspozytora MVC Spring i wszystkie procedury obsługi MVC zostały zainicjowane.
Możliwe jest przechwycenie tego wyjątku za pomocą niestandardowego filtru i zbudowanie własnej serializacji JSON od zera. W takim przypadku otrzymamy kod całkowicie niezależny od reszty wiosennej infrastruktury MVC. To nie jest dobre.
Rozwiązanie, które znalazłem, działa, ale wygląda na szalone.
@Configuration
public class CustomSecurityConfiguration extends
WebSecurityConfigurerAdapter {
@Autowired
protected RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@Autowired
protected GlobalExceptionHandler exceptionHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.fullyAuthenticated();
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint());
}
public AuthenticationEntryPoint authenticationEntryPoint() {
return new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
try {
ResponseEntity<ExceptionResponse> objResponse = exceptionHandler.authenticationException(authException);
Method unknownException = exceptionHandler.getClass().getMethod("authenticationException", AuthenticationException.class);
HandlerMethod handlerMethod = new HandlerMethod(exceptionHandler, unknownException);
MethodParameter returnType = handlerMethod.getReturnValueType(objResponse);
ModelAndViewContainer mvc = new ModelAndViewContainer(); // not really used here.
List<HttpMessageConverter<?>> mconverters = requestMappingHandlerAdapter.getMessageConverters();
DispatcherServletWebRequest webRequest = new DispatcherServletWebRequest(request, response);
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(mconverters);
processor.handleReturnValue(objResponse, returnType, mvc, webRequest);
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new ServletException(e);
}
}
};
}
Czy istnieje sposób na wykorzystanie wiosna rury serializacji (z wiosny budować konwertery wiadomości, Format negocjacji MIME itp), który wygląda lepiej niż to?
Oto nieco bardziej eleganckie rozwiązanie, bardzo podobne do twojego, ale zawijanie oryginalnego wyjątku w wyjątek, który umożliwia "złapanie" przez @ExceptionHandler: https://stackoverflow.com/questions/43632565/exceptionhandler-for- a-pre-controller-filter-spring-security/43636386 – spekdrum
http://www.baeldung.com/spring-security-custom-access-denied-page –