Bir REST hizmeti geliştiriyorum. JSON kullanır ve bir sorun olduğunda önceden tanımlanmış bazı JSON nesnelerini iade etmelidir. Varsayılan Bahar yanıtı şöyle:Spring MVC (veya Spring Boot). Güvenlikle ilgili istisnalar için özel JSON yanıtı 401 Yetkilendirilmemiş veya 403 Yasak)
{
"timestamp": 1512578593776,
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/swagger-ui.html"
}
I (a stacktrace ve ek istisna ilgili bilgilerle) kendine ait bir ile bu varsayılan JSON değiştirmek istiyor.
Yay, varsayılan davranışların üzerine yazmanın kullanışlı bir yolunu sunar. Özel bir özel durum işleyici ile bir @RestControllerAdvice
fasulye tanımlamalıdır. Bu
@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
}
}
özel gibi ExceptionResponse
nesne daha sonra özel bir mesaj dönüştürücü kullanılarak Bahar tarafından JSON dönüştürülecektir.
SORUN IS, InsufficientAuthenticationException
gibi güvenlik istisnalar @ExceptionHandler
olarak açıklamalı bir yöntemle ele alınamaz. Bu tür istisnalar, Spring MVC dağıtıcı sunucu uygulamasının girilmesinden önce gerçekleşir ve tüm MVC işleyicileri başlatıldı.
Özel bir süzgeç kullanarak bu özel durumu engellemek ve sıfırdan kendi JSON serileştirmesini oluşturmak mümkündür. Bu durumda, Spring MVC altyapısının geri kalanından tamamen bağımsız bir kod alacaktı. İyi değil.
Bulduğum çözüm işe yarıyor gibi görünüyor, ama delirmiş görünüyor.
@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);
}
}
};
}
bu daha iyi görünüyor (, mesaj konvertörlerindeki MIME biçimi müzakere vb inşa Bahar ile birlikte) Bahar seri boru kullanmak için bir yolu var mı?
Buradakine benzer, ancak orijinal istisnayı @ExceptionHandler tarafından "yakalanmasına" izin veren bir istisnayla sarmak gibi daha zarif bir çözüm: https://stackoverflow.com/questions/43632565/exceptionhandler-for- Ön kontrolör filtre yaylı güvenlik/43636386 – spekdrum
http://www.baeldung.com/spring-security-custom-access-denied-page –