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认证。
正确实现步骤
- 先构建支持NTLM认证的WebClient,专门用于请求Token接口。
- 调用Token接口获取Bearer Token。
- 用获取到的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
相关产品推荐
相关产品推荐

