Spring RestTemplate 和代理验证
Spring RestTemplate and Proxy Auth
我正在尝试使用 Spring 进行 REST 调用。据我了解,正确的方法是使用 RestTemplate
(?)。问题是,我在代理后面。
这是我现在的代码:
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
InetSocketAddress address = new InetSocketAddress(host, 3128);
Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(factory);
似乎可行,但我需要在代理处进行身份验证,但这是如何完成的? Proxy
类型和 SimpleClientHttpRequestFactory
类型似乎不处理凭据。没有凭据,我只会得到 407...
下面的代码对我有用。
RestTemplate restTemplate = new RestTemplate();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( new AuthScope("proxyHost", "proxyPort"), new UsernamePasswordCredentials("proxyUser", "proxyPass") );
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost("proxyHost", "proxyPort"));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
CloseableHttpClient client = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);
restTemplate.setRequestFactory(factory);
经过很多不同的选择后,我选择了下面的代码,因为能够在创建时为 RestTemplate 设置代理,因此我可以将它重构为一个单独的方法。请注意,它还有一个额外的依赖项,因此请记住这一点。
private RestTemplate createRestTemplate() throws Exception {
final String username = "myusername";
final String password = "myPass";
final String proxyUrl = "proxy.nyc.bigtower.com";
final int port = 8080;
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxyUrl, port),
new UsernamePasswordCredentials(username, password)
);
HttpHost myProxy = new HttpHost(proxyUrl, port);
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider).disableCookieManagement();
HttpClient httpClient = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(httpClient);
return new RestTemplate(factory);
}
//我用的依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
如果您的代理需要基本身份验证,您只需设置 HTTP header Proxy-Authorization
来处理身份验证:
final SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
final InetSocketAddress address = new InetSocketAddress(host, 3128);
final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);
final String username = "Aladdin";
final String password = "open sesame";
final RestTemplate restTemplate = new RestTemplateBuilder()
.requestFactory(() -> factory)
.defaultHeader(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ':' + password).getBytes(StandardCharsets.UTF_8)))
.build();
您不需要为此使用额外的依赖项。
我正在尝试使用 Spring 进行 REST 调用。据我了解,正确的方法是使用 RestTemplate
(?)。问题是,我在代理后面。
这是我现在的代码:
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
InetSocketAddress address = new InetSocketAddress(host, 3128);
Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(factory);
似乎可行,但我需要在代理处进行身份验证,但这是如何完成的? Proxy
类型和 SimpleClientHttpRequestFactory
类型似乎不处理凭据。没有凭据,我只会得到 407...
下面的代码对我有用。
RestTemplate restTemplate = new RestTemplate();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( new AuthScope("proxyHost", "proxyPort"), new UsernamePasswordCredentials("proxyUser", "proxyPass") );
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost("proxyHost", "proxyPort"));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
CloseableHttpClient client = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);
restTemplate.setRequestFactory(factory);
经过很多不同的选择后,我选择了下面的代码,因为能够在创建时为 RestTemplate 设置代理,因此我可以将它重构为一个单独的方法。请注意,它还有一个额外的依赖项,因此请记住这一点。
private RestTemplate createRestTemplate() throws Exception {
final String username = "myusername";
final String password = "myPass";
final String proxyUrl = "proxy.nyc.bigtower.com";
final int port = 8080;
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxyUrl, port),
new UsernamePasswordCredentials(username, password)
);
HttpHost myProxy = new HttpHost(proxyUrl, port);
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider).disableCookieManagement();
HttpClient httpClient = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(httpClient);
return new RestTemplate(factory);
}
//我用的依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
如果您的代理需要基本身份验证,您只需设置 HTTP header Proxy-Authorization
来处理身份验证:
final SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
final InetSocketAddress address = new InetSocketAddress(host, 3128);
final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);
final String username = "Aladdin";
final String password = "open sesame";
final RestTemplate restTemplate = new RestTemplateBuilder()
.requestFactory(() -> factory)
.defaultHeader(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ':' + password).getBytes(StandardCharsets.UTF_8)))
.build();
您不需要为此使用额外的依赖项。