SpringBoot 3.3 RestClient代理与认证配置返回401问题
问题分析
你遇到的401 Unauthorized错误,是因为目标服务http://test.org要求Basic认证,但你只配置了代理服务器的认证凭据,未为目标服务添加对应认证信息。日志中的「No credentials for basic schema」明确指向目标服务的Basic认证缺少有效凭据,且请求已成功通过代理建立连接,排除代理认证的问题。
另外,你的代码中重复执行了两次clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider);,属于冗余代码,可删除其中一次。
解决方案
方案1:通过CredentialsProvider同时配置代理与目标服务认证
在CredentialsProvider中添加目标服务的AuthScope和凭据,让HttpClient自动处理两者的Basic认证:
proxyUrl = "proxy.ops.org"; proxyport = 8080; // 目标服务的地址与端口 String targetHost = "test.org"; int targetPort = 80; CredentialsProvider credsProvider = new BasicCredentialsProvider(); // 配置代理服务器的认证凭据 credsProvider.setCredentials( new AuthScope(proxyUrl, proxyport), new UsernamePasswordCredentials(proxyUsername, proxyPassword) ); // 配置目标服务的Basic认证凭据 credsProvider.setCredentials( new AuthScope(targetHost, targetPort), new UsernamePasswordCredentials(targetUsername, targetPassword) ); HttpHost myProxy = new HttpHost(proxyUrl, proxyport); HttpClientBuilder clientBuilder = HttpClientBuilder.create(); // 仅需一次配置代理与凭据提供者 clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider); HttpClient httpClient = clientBuilder.build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setHttpClient(httpClient); RestClient restClient = RestClient.builder() .baseUrl("http://test.org") .requestFactory(factory) .build();
方案2:手动添加目标服务的Authorization请求头
如果不想通过CredentialsProvider统一管理,也可以在请求时直接添加Basic认证头:
import java.util.Base64; import java.nio.charset.StandardCharsets; // 生成Basic认证的Header值 String targetAuth = targetUsername + ":" + targetPassword; String encodedAuth = Base64.getEncoder().encodeToString(targetAuth.getBytes(StandardCharsets.UTF_8)); String authHeader = "Basic " + encodedAuth; ResponseEntity<String> result = restClient.get() .uri(url) .accept(MediaType.APPLICATION_JSON) .header("Authorization", authHeader) .retrieve() .toEntity(String.class);
额外检查点
- 确认代理服务器的凭据
proxyUsername、proxyPassword是否有效,若担心AuthScope匹配问题,可添加AuthScope.ANY_REALM增强匹配度:credsProvider.setCredentials( new AuthScope(proxyUrl, proxyport, AuthScope.ANY_REALM), new UsernamePasswordCredentials(proxyUsername, proxyPassword) ); - 验证目标服务的
targetUsername、targetPassword是否正确,可通过Postman等工具直接调用目标API确认认证有效性。
内容的提问来源于stack exchange,提问作者Rajar R
相关产品推荐
相关产品推荐

