spring-security 从Sping Boot 筛选器发送Restful API JSON响应

wwodge7n  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(104)

我正在使用下面的过滤器来检查API请求中是否存在特定的HTTP头。

@Component
@RequiredArgsConstructor
public class HeaderValidationFilter extends OncePerRequestFilter {
private final ObjectMapper objectMapper;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

String headerValue = request.getHeader("RANDOM_HEADER");

if(Objects.isNull(headerValue)) {
    ResponseEntity<Object> responseToSend = ResponseGen.create("FAILED", "Missing Authentication Header", new Object())));

    response.setHeader("Content-Type", "application/json");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    response.getOutputStream().write(responseToSend);
    return;
}

    filterChain.doFilter(request, response);
}

它以JSON的形式返回响应,但添加了对象键,如headersstatusCode等,我提供的有效负载放在body中。由于我在项目中定义了标准错误响应,因此我无法以原样返回响应。(请参见以下响应)

{
"headers": {},
"body": {
    "status": "FAILURE",
    "message": "Missing Authentication Header",
    "data": {}
},
"statusCode": "UNAUTHORIZED",
"statusCodeValue": 401
}

我只希望响应采用以下格式:

{
    "status": "FAILED",
    "message": "Missing Authentication Header",
    "data": {}
}

我尝试过使用@ControllerAdvice的通用异常处理程序返回,但它没有从Filters捕获异常,因为它在DispatcherServlet之前执行
有人能帮我吗?

n1bvdmb6

n1bvdmb61#

您看到的JSON

{
"headers": {...},
"body": {...},
"statusCode": ...,
"statusCodeValue": ...
}

是序列化的ResponseEntity,您可以将其写入筛选器作为响应:

ResponseEntity<Object> responseToSend = ResponseGen.create("FAILED", "Missing Authentication Header", new Object())));

显然,如果你需要另一种格式的响应,你必须使用一个序列化为所需格式的对象作为响应。

@Data
@AllArgsConstructor
class StandardError {
    private String status;
    private String message;
    private Object data;
}

....

@Override
protected void doFilterInternal(HttpServletRequest request, 
                                HttpServletResponse response, 
                                FilterChain filterChain) throws ServletException, IOException {
    ...
    if (Objects.isNull(headerValue)) {
        StandardError responseToSend = new StandardError("FAILED", "Missing Authentication Header", new Object());

        response.setHeader("Content-Type", "application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getOutputStream().write(responseToSend);
        return;
    }
    ...

相关问题