【发布时间】:2021-01-28 14:06:13
【问题描述】:
我正在构建一个 REST API,它使用 Spring Security(及其过滤器链)通过 JWT 对用户进行身份验证。现在,如果这样的 JWT 丢失、过期或类似情况,我想向 API 使用者返回格式正确的错误消息,而不是默认的白标签错误响应。从 Spring Security 过滤器返回的 API 错误消息应该与业务逻辑失败时返回的错误消息相同。
如果业务逻辑失败,我的 Spring REST 控制器会返回格式如下的错误消息(通过@RestControllerAdvice):
Content-Type: application/json
{
"code": "VOUCHER_NOT_FOUND",
"message": "The specified voucher code was not found.",
"timestamp": "2020-09-06T21:22:23.015Z"
}
我知道如果 Spring Security 过滤器链中发生错误,控制器将永远无法到达,因此我必须从安全过滤器中返回一条 HTTP 错误消息。我试过这样做:
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
@Override
protected final void doFilterInternal(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain)
throws IOException, ServletException {
try {
// Perform various auth checks here
// Throw JwtAuthorizationException if a check fails
chain.doFilter(request, response);
} catch (JwtAuthorizationFailedException e) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setHeader("Content-Type", "application/json"); // does not work
response.getWriter().write("{ \"Simple\": \"Test\" }");
}
}
问题是,我得到的错误消息总是设置不同的Content-Type 标头(添加了charset=ISO-8859-1):
Content-Type: application/json;charset=ISO-8859-1
{
"Simple": "Test"
}
我想简化这一点并使其保持一致。所以问题是,我怎样才能确定,只有
Content-Type: application/json
是从安全过滤器返回的?我尝试了很多选择,比如
response.setHeader("Content-Type", "application/json");
或
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
但所有这些都不起作用。有什么想法吗?
【问题讨论】:
标签: java spring-boot rest spring-security