Spring WebClient实现Windows NTLM认证及免密认证方法咨询
问题背景
我找不到清晰解释相关内容的优质示例或文档,不过已经通过旧版RestTemplate成功完成NTLM认证,代码如下:
HttpClientBuilder httpClient = HttpClients.custom(); BasicCredentialsProvider provider = new BasicCredentialsProvider(); Credentials cred = new NTCredentials("my-user", "my-password", null, "my-domain"); provider.setCredentials(AuthScope.ANY, cred); httpClient.setDefaultCredentialsProvider(provider); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient.build()); RestTemplate restTemplate = new RestTemplate(requestFactory); restTemplate.getForEntity("https://my.url.com", String.class);
但我还没找到把NTCredentials(或Credentials)传入WebClient的方法,试过以下两种方式都无效:
方式一:
WebClient client = WebClient.builder() .filter(ExchangeFilterFunctions.basicAuthentication("user", "password")) .build();
方式二:
WebClient client = WebClient.builder().build(); client.get().headers(h -> h.setBasicAuth("user", "password"))...
问题
- 如何使用Spring WebClient实现Windows/NTLM认证?
- 在Windows环境下运行时,能否无需提供账号密码,使用当前用户上下文实现NTLM或Windows认证?
解决方案
1. WebClient实现NTLM认证
WebClient本身没有直接支持NTLM的API,需要结合Apache HttpClient的异步客户端(HttpAsyncClient)来实现,步骤如下:
首先,构建带有NTCredentials的异步HttpClient:
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); Credentials ntCreds = new NTCredentials("my-user", "my-password", null, "my-domain"); credentialsProvider.setCredentials(AuthScope.ANY, ntCreds); CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom() .setDefaultCredentialsProvider(credentialsProvider) .build();
然后,将这个异步HttpClient适配为Spring的ClientHttpConnector,再传入WebClient:
ClientHttpConnector connector = new HttpComponentsClientHttpConnector(asyncHttpClient); WebClient webClient = WebClient.builder() .clientConnector(connector) .build();
这样WebClient就可以通过NTLM认证请求目标接口了:
webClient.get() .uri("https://my.url.com") .retrieve() .bodyToMono(String.class) .block();
2. 使用当前Windows用户上下文实现无密码认证
可以利用Windows的SSPI(安全支持提供者接口)实现自动使用当前登录用户的凭据进行NTLM认证,同样需要借助Apache HttpClient的配置:
步骤1:添加依赖
如果使用Maven,确保项目中包含Apache HttpClient的Windows集成依赖:
<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5-win</artifactId> <version>5.2.1</version> </dependency>
步骤2:构建支持SSPI的异步HttpClient
CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom() .setDefaultCredentialsProvider(new BasicCredentialsProvider()) .setDefaultAuthSchemeRegistry(AuthSchemeRegistries.createDefault()) .build();
步骤3:配置WebClient
同样将这个客户端适配为ClientHttpConnector并传入WebClient:
ClientHttpConnector connector = new HttpComponentsClientHttpConnector(asyncHttpClient); WebClient webClient = WebClient.builder() .clientConnector(connector) .build();
此时,在Windows环境下运行时,WebClient会自动使用当前登录用户的上下文进行NTLM认证,无需手动输入账号密码。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

