Spring AuthenticationEntryPoint 返回 Tomcat HTML 错误而不是 JSON
Posted
技术标签:
【中文标题】Spring AuthenticationEntryPoint 返回 Tomcat HTML 错误而不是 JSON【英文标题】:Spring AuthenticationEntryPoint returns Tomcat HTML error instead of JSON 【发布时间】:2018-03-03 02:25:15 【问题描述】:我正在使用 Spring 在更大的应用程序中公开 API。当访问位于 authenticated() 配置后面的端点时,我的应用程序会因为以下代码而抛出一个丑陋的 Tomcat html 错误:
@Component
public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException, ServletException
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
但是,由于这是一个 API,我只想返回 JSON,就像我的 API 的其余部分一样。对于正常的异常处理,我设置了以下@ControllerAdvice
:
@ControllerAdvice
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler
/**
* Default internal BadCredentialsException handler. Respond with 401 Unauthorized
*/
@ExceptionHandler(value = BadCredentialsException.class)
public ResponseEntity<Object> handleBadCredentialsException(BadCredentialsException e, WebRequest request)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return handleExceptionInternal(e, null, headers, HttpStatus.UNAUTHORIZED, request);
/**
* Fallback default exception handler. Respond with 500
*/
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Object> handleFallbackException(Exception e, WebRequest request)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return handleExceptionInternal(e, null, headers, HttpStatus.INTERNAL_SERVER_ERROR, request);
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body,
HttpHeaders headers, HttpStatus status, WebRequest request)
final ErrorResponse error = new ErrorResponse(status, ex.getMessage());
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status))
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
return new ResponseEntity<Object>(error, headers, status);
ErrorResponse
是我自己的小响应包装器,其中包含 HttpStatus 代码和异常消息。这被格式化为 JSON 格式:
"status": 401,
"message": "Bad credentials"
我如何确保我的AuthenticationEntryPoint
只有一个请求和响应对象才能返回类似格式的错误,而不是丑陋的 Tomcat HTML 页面。
【问题讨论】:
Handle spring security authentication exceptions with @ExceptionHandler的可能重复 【参考方案1】:您可以根据需要更改HttpServletResponse
。
看一看:https://***.com/a/19788700/1490806
【讨论】:
手动编写 JSON 字符串或使用 ObjectMapper 感觉非常丑陋和 hacky。真的没有合适的方法来做到这一点吗?感觉就像我错误地使用了 Spring。如果您需要在此 AuthenticationEntryPoint 中再次执行此操作,那么在 1 个位置定义您的异常处理有什么意义? spring 安全过滤器发生在 spring dispatcher servlet 之前。所以我猜春天无法控制安全过滤器链上发生的异常。 visola.github.io/img/blog/spring-security-architecture.png我不知道有其他方法可以做到这一点。以上是关于Spring AuthenticationEntryPoint 返回 Tomcat HTML 错误而不是 JSON的主要内容,如果未能解决你的问题,请参考以下文章
Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC
学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签
Spring框架--Spring事务管理和Spring事务传播行为