Apache HTTPCLIENT基本身份验证
Contents
1. 概述
本教程将说明如何在 Apache HttpClient 上配置基本身份验证。
如果您想更深入地挖掘并学习可以使用 HttpClient 做的其他很酷的事情——请继续阅读** HttpClient 教程 **。
2. 使用 API 进行基本身份验证
让我们从在 HttpClient 上配置基本身份验证的标准方法开始 - 通过CredentialsProvider:
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials
= new UsernamePasswordCredentials("user1", "user1Pass");
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider)
.build();
HttpResponse response = client.execute(
new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION));
int statusCode = response.getStatusLine()
.getStatusCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
正如我们所见,使用凭据提供程序创建客户端并使用基本身份验证进行设置并不困难。
现在,要了解HttpClient在幕后实际执行的操作,我们需要查看日志:
# ... request is sent with no credentials
[main] DEBUG ... - Authentication required
[main] DEBUG ... - localhost:8080 requested authentication
[main] DEBUG ... - Authentication schemes in the order of preference:
[negotiate, Kerberos, NTLM, Digest, Basic]
[main] DEBUG ... - Challenge for negotiate authentication scheme not available
[main] DEBUG ... - Challenge for Kerberos authentication scheme not available
[main] DEBUG ... - Challenge for NTLM authentication scheme not available
[main] DEBUG ... - Challenge for Digest authentication scheme not available
[main] DEBUG ... - Selected authentication options: [BASIC]
# ... the request is sent again - with credentials
整个客户端-服务器通信现在很清楚:
- 客户端发送没有凭据的 HTTP 请求
- 服务器发回一个挑战
- 客户端协商并确定正确的身份验证方案
- 客户端发送第二个 Request,这次使用凭据
3. 抢先式基本认证
开箱即用,HttpClient不进行抢先式身份验证。相反,这必须是客户做出的明确决定。
首先,我们需要创建HttpContext——使用预先选择了正确类型的身份验证方案的**身份验证缓存预先填充它。**这将意味着不再需要前面示例中的协商 -已选择基本身份验证:
HttpHost targetHost = new HttpHost("localhost", 8082, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS));
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
现在我们可以使用带有新上下文的客户端并发送预认证请求:
HttpClient client = HttpClientBuilder.create().build();
response = client.execute(
new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION), context);
int statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
让我们看一下日志:
[main] DEBUG ... - Re-using cached 'basic' auth scheme for http://localhost:8082
[main] DEBUG ... - Executing request GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1
[main] DEBUG ... >> GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1
[main] DEBUG ... >> Host: localhost:8082
[main] DEBUG ... >> Authorization: Basic dXNlcjE6dXNlcjFQYXNz
[main] DEBUG ... << HTTP/1.1 200 OK
[main] DEBUG ... - Authentication succeeded
一切看起来都不错:
- 预选“基本认证”方案
- 请求与Authorization标头一起发送
- 服务器以200 OK响应
- 认证成功
4. 使用原始 HTTP 标头的基本身份验证
抢先式基本身份验证基本上意味着预先发送AUTHORIZATION标头。
因此,我们可以控制此标头并手动构建它,而不是通过之前相当复杂的示例来设置它:
HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
String auth = DEFAULT_USER + ":" + DEFAULT_PASS;
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(StandardCharsets.ISO_8859_1));
String authHeader = "Basic " + new String(encodedAuth);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
让我们确保它正常工作:
[main] DEBUG ... - Auth cache not set in the context
[main] DEBUG ... - Opening connection {}->http://localhost:8080
[main] DEBUG ... - Connecting to localhost/127.0.0.1:8080
[main] DEBUG ... - Executing request GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1
[main] DEBUG ... - Proxy auth state: UNCHALLENGED
[main] DEBUG ... - http-outgoing-0 >> GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1
[main] DEBUG ... - http-outgoing-0 >> Authorization: Basic dXNlcjE6dXNlcjFQYXNz
[main] DEBUG ... - http-outgoing-0 << HTTP/1.1 200 OK
因此,即使没有 auth 缓存,Basic Authentication 仍然可以正常工作,我们会收到200 OK。