代码之家  ›  专栏  ›  技术社区  ›  lightningbolt6

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

  •  0
  • lightningbolt6  · 技术社区  · 2 年前

    我正在尝试使用WebClient在我的SpringBoot应用程序中使用RESTneneneba API。

    这个特定的API在URL中以基本身份验证用户名和密码作为参数,格式如下 http://username:password@hostname:8080/api/route

    我目前正在构建完整的URL,包括用户名、密码和路由,并在提出请求时将其传递给Web客户端,但似乎Web客户端没有正确发送身份验证参数。

    我当前的设置如下:

    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 - how to get request body? )它记录请求和响应方法、URI、正文和标头。它将URI作为 /api/route 和主机头作为 host: localhost:8080 。从输出中我看不出身份验证参数是否真的被传递到了服务器。

    有人知道我是否必须做一些特殊的事情才能将身份验证参数作为WebClient中URL的一部分传递吗?

    1 回复  |  直到 2 年前
        1
  •  2
  •   Au Wai Lun    2 年前

    要在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());
    }