从带有 HttpClient 4.3 编辑的 http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/:
Spring 3.0和3.1以及现在的4.x都对Apache HTTP库有很好的支持:
-
Spring 3.0,与现已停产的 HttpClient 3.x 集成
CommonsClientHttpRequestFactory
-
Spring 3.1 引入了对当前 HttpClient 4.x 通过的支持(在 JIRA SPR-6180 中添加了支持)
HttpComponentsClientHttpRequestFactory
)
-
Spring 4.0 通过
HttpComponentsAsyncClientHttpRequestFactory
让我们开始使用 HttpClient 4 和 Spring 4 进行设置。
这将需要一个HTTP请求工厂 - 一个支持基本身份验证的工厂 - 到目前为止,一切都很好。然而,直接使用现有的将被证明是困难的,因为的架构设计没有很好的支持 - 一个工具性的拼图。因此,我们需要子类化并覆盖该方法:(取自GitHub上的soluvas框架)RestTemplate
HttpComponentsClientHttpRequestFactory
RestTemplate
HttpContext
HttpComponentsClientHttpRequestFactory
createHttpContext
)
package org.soluvas.commons.util;
import java.net.URI;
import javax.annotation.Nullable;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* From http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/
*
* <p>And with that, everything is in place – the {@link RestTemplate} will now be able to support the Basic Authentication scheme; a simple usage pattern would be:
*
* <pre>
* final AuthHttpComponentsClientHttpRequestFactory requestFactory = new AuthHttpComponentsClientHttpRequestFactory(
* httpClient, host, userName, password);
* final RestTemplate restTemplate = new RestTemplate(requestFactory);
* </pre>
*
* And the request:
*
* <pre>
* restTemplate.get("http://localhost:8080/spring-security-rest-template/api/foos/1", Foo.class);
* </pre>
*
* @author anton
*/
public class AuthHttpComponentsClientHttpRequestFactory extends
HttpComponentsClientHttpRequestFactory {
protected HttpHost host;
@Nullable
protected String userName;
@Nullable
protected String password;
public AuthHttpComponentsClientHttpRequestFactory(HttpHost host) {
this(host, null, null);
}
public AuthHttpComponentsClientHttpRequestFactory(HttpHost host, @Nullable String userName, @Nullable String password) {
super();
this.host = host;
this.userName = userName;
this.password = password;
}
public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host) {
this(httpClient, host, null, null);
}
public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host,
@Nullable String userName, @Nullable String password) {
super(httpClient);
this.host = host;
this.userName = userName;
this.password = password;
}
@Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(host, basicAuth);
// Add AuthCache to the execution context
HttpClientContext localcontext = HttpClientContext.create();
localcontext.setAuthCache(authCache);
if (userName != null) {
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(userName, password));
localcontext.setCredentialsProvider(credsProvider);
}
return localcontext;
}
}
正是在这里 - 在创建 - 内置了基本的身份验证支持。如您所见,使用 HttpClient 4.x 执行抢占式基本身份验证有点负担:身份验证信息被缓存,设置此身份验证缓存的过程非常手动且不直观。HttpContext
这样,一切都已准备就绪 - 现在将能够支持基本身份验证方案;一个简单的使用模式是:RestTemplate
final AuthHttpComponentsClientHttpRequestFactory requestFactory =
new AuthHttpComponentsClientHttpRequestFactory(
httpClient, host, userName, password);
final RestTemplate restTemplate = new RestTemplate(requestFactory);
和请求:
restTemplate.get(
"http://localhost:8080/spring-security-rest-template/api/foos/1",
Foo.class);
有关如何保护 REST 服务本身的深入讨论,请查看本文。