spring Sping Boot WebClient -URL中的基本身份验证(用户名和密码)(401)

ldfqzlk8  于 2023-09-29  发布在  Spring
关注(0)|答案(1)|浏览(211)

我正在尝试使用WebClient在Sping Boot 应用程序中使用REST API。
这个特殊的API将basic-auth用户名和密码作为URL中的参数,格式为http://username:password@hostname:8080/api/route
我目前正在构建完整的URL,包括用户名,密码和路由,并在我发出请求时将其传递给WebClient,但WebClient似乎没有正确发送身份验证参数。
我的当前设置如下:

URI url = new URI("http://username:password@hostname:8080/api/route");

WebClient.Builder webClientBuilder = WebClient.builder()
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        
WebClient webClient = webClientBuilder.build(); // I also have a customizer to add logging to the requests and responses

String requestBody = ""; // The body does not matter for this example

try {
            response = webClient.post()
            .uri(url)
            .bodyValue(requestBody)
            .retrieve()
            .bodyToMono(String.class)
            .toFuture()
            .get();
        } catch (Exception e) {
            logger.error(e.toString());
        }

我收到一个401未经授权的每一次我提出一个请求使用此设置。当我在Postman中使用相同的URL手动发出相同的请求时,我能够从服务器收到授权的响应。在我看来,WebClient似乎正在从调用中剥离身份验证参数。
我有一个日志定制器(像这样的答案WebClient -如何获得请求体?),它记录请求和响应方法、URI、正文和头。它给出的URI为/api/route,主机头为host: localhost:8080。我无法从输出中看出身份验证参数是否实际上被传递到服务器。
有谁知道我是否必须做一些特殊的事情才能在WebClient中将身份验证参数作为URL的一部分传递?

2vuwiymt

2vuwiymt1#

要在WebClient中传递基本身份验证参数,可以使用Spring Security提供的BasicAuthenticationInterceptor类。以下是如何修改代码以包含基本身份验证:

URI url = new URI("http://hostname:8080/api/route");
String username = "username";
String password = "password";

WebClient.Builder webClientBuilder = WebClient.builder()
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .filter(basicAuthentication(username, password));

WebClient webClient = webClientBuilder.build();

String requestBody = ""; // The body does not matter for this example

try {
    String response = webClient.post()
            .uri(url)
            .bodyValue(requestBody)
            .retrieve()
            .bodyToMono(String.class)
            .block(); // Use block() instead of toFuture().get()
    
    // Process the response
} catch (Exception e) {
    logger.error(e.toString());
}

相关问题