首页 > 解决方案 > 无法使用 Webflux authenticationFailureHandler 返回 JSON 数据

问题描述

我正在构建一个 React SPA,并希望使用 JSON 与后端进行交互。当身份验证失败时,我希望能够以 JSON 的形式发送自定义错误消息。但是,鉴于以下代码:

    .authenticationFailureHandler(((exchange, e) -> {
      return Mono.fromRunnable(() -> {
        ServerHttpResponse response = exchange.getExchange().getResponse();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        DataBuffer buf = exchange.getExchange().getResponse().bufferFactory().wrap("{\"test\":\"tests\"}".getBytes(StandardCharsets.UTF_8));
        response.writeWith(Mono.just(buf));
      });
    })

我收到以下错误:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
Referrer-Policy: no-referrer
content-length: 0

<Response body is empty>

Response code: 200 (OK); Time: 1162ms; Content length: 0 bytes

但是,如果我更改响应代码,它会反映在响应中,所以我知道代码已执行但没有返回响应正文。

当身份验证失败时,我需要更改什么才能发回响应正文?

标签: javaspring-bootspring-securityspring-webflux

解决方案


我认为这可以工作:

.authenticationFailureHandler(((exchange, e) -> {
        ServerHttpResponse response = exchange.getExchange().getResponse();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        DataBuffer buf = exchange.getExchange().getResponse().bufferFactory().wrap("{\"test\":\"tests\"}".getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Mono.just(buf));
      });
    })

可能有比将 JSON 写为字符串更好的方法,但我相信这应该可行。您的尝试不起作用,因为没有订阅返回Publisherresponse.writeWith(Mono.just(buf)). 由于发布者很懒惰,因此不会向响应中写入任何内容。


推荐阅读