You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot WebClient配置NTLM认证遇401未授权问题咨询

问题分析与解决方案

你的实现不正确,核心问题是完全跳过了Postman流程里的第一步(获取NTLM认证后的Token),并且错误地将NTLM认证配置应用到了不需要该认证的员工接口请求上。

具体问题点

  • 没有执行http://example.com:83/api/auth/token的请求来获取Bearer Token,直接调用了需要Token的员工接口,自然会返回401。
  • 你给WebClient配置的NTLM认证只适用于83端口的token接口,但89端口的员工接口需要的是Bearer Token,而非NTLM认证。

正确实现步骤

  1. 先构建支持NTLM认证的WebClient,专门用于请求Token接口。
  2. 调用Token接口获取Bearer Token。
  3. 用获取到的Token作为请求头,调用员工接口。

修正后的代码示例

// 1. 构建支持NTLM认证的WebClient,用于获取Token
BasicCredentialsProvider tokenProvider = new BasicCredentialsProvider();
tokenProvider.setCredentials(
    new AuthScope("example.com", 83, "/api/auth/token", StandardAuthScheme.NTLM),
    new NTCredentials("testuser", "pwd".toCharArray(), null, null)
);

WebClient tokenWebClient = WebClient.builder()
    .clientConnector(new HttpComponentsClientHttpConnector(
        HttpAsyncClients.custom()
            .setDefaultCredentialsProvider(tokenProvider)
            .setTargetAuthenticationStrategy(DefaultAuthenticationStrategy.INSTANCE)
            .setDefaultRequestConfig(RequestConfig.custom()
                .setAuthenticationEnabled(true)
                .setTargetPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.NTLM))
                .build())
            .build()
    ))
    .build();

// 2. 请求Token接口,获取Bearer Token
String token = tokenWebClient.get()
    .uri("http://example.com:83/api/auth/token")
    .retrieve()
    .bodyToMono(new ParameterizedTypeReference<LinkedHashMap<String, Object>>() {})
    .map(response -> (String) response.get("token")) // 假设返回的JSON里token字段是"token"
    .block();

// 3. 调用员工接口,携带Bearer Token
WebClient employeeWebClient = WebClient.builder().build();

Map<String, Object> body = new HashMap<>();
body.put("test-key", "value");

ParameterizedTypeReference<LinkedHashMap<String, Object>> resultType =
    new ParameterizedTypeReference<LinkedHashMap<String, Object>>() {};

LinkedHashMap<String, Object> result = employeeWebClient.post()
    .uri("http://example.com:89/api/v1/employee")
    .contentType(MediaType.APPLICATION_JSON)
    .accept(MediaType.ALL)
    .header(HttpHeaders.AUTHORIZATION, "Bearer " + token) // 添加Bearer Token头
    .bodyValue(body)
    .retrieve()
    .bodyToMono(resultType)
    .block();

额外注意事项

  • 确认Token接口返回的JSON结构,调整response.get("token")中的字段名,匹配实际返回的Token字段。
  • 生产环境中建议使用非阻塞的subscribe()替代block(),避免阻塞线程。
  • 如果两个接口属于同一域名但不同端口,也可以复用WebClient,但分开构建不同用途的WebClient逻辑更清晰,避免认证规则冲突。

内容的提问来源于stack exchange,提问作者Lolly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:40:33