HttpClientBuilder基本身份验证

从HttpClient 4.3开始,我一直在使用HttpClientBuilder。我正在连接到具有基本身份验证的REST服务。我将凭据设置如下:

HttpClientBuilder builder = HttpClientBuilder.create();

// Get the client credentials

String username = Config.get(Constants.CONFIG_USERNAME);

String password = Config.get(Constants.CONFIG_PASSWORD);

// If username and password was found, inject the credentials

if (username != null && password != null)

{

CredentialsProvider provider = new BasicCredentialsProvider();

// Create the authentication scope

AuthScope scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM);

// Create credential pair

UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);

// Inject the credentials

provider.setCredentials(scope, credentials);

// Set the default credentials provider

builder.setDefaultCredentialsProvider(provider);

}

但是,这不起作用(我正在使用的REST服务返回401)。怎么了?

回答:

从此处的 文档中:

http://hc.apache.org/httpcomponents-client-

ga/tutorial/html/authentication.html

默认情况下,httpclient不会抢先提供凭据,它将首先创建一个没有身份验证参数的HTTP请求。这是设计使然,出于安全预防措施以及作为规范的一部分。但是,如果您不重试连接,或者连接到的任何地方希望您在第一个连接上发送身份验证详细信息,就会引起问题。由于您需要拨打多个电话,因此还会导致请求的额外延迟,并使401s出现在日志中。

解决方法是使用身份验证缓存来假装您已经连接到服务器一次。这意味着您只会进行一次HTTP调用,而不会在日志中看到401:

CloseableHttpClient httpclient = HttpClientBuilder.create().build();

HttpHost targetHost = new HttpHost("localhost", 80, "http");

CredentialsProvider credsProvider = new BasicCredentialsProvider();

credsProvider.setCredentials(

new AuthScope(targetHost.getHostName(), targetHost.getPort()),

new UsernamePasswordCredentials("username", "password"));

// 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(targetHost, basicAuth);

// Add AuthCache to the execution context

HttpClientContext context = HttpClientContext.create();

context.setCredentialsProvider(credsProvider);

context.setAuthCache(authCache);

HttpGet httpget = new HttpGet("/");

for (int i = 0; i < 3; i++) {

CloseableHttpResponse response = httpclient.execute(

targetHost, httpget, context);

try {

HttpEntity entity = response.getEntity();

} finally {

response.close();

}

}

请注意:您需要信任要连接的主机,如果使用的是HTTP,则用户名和密码将以明文形式发送(好吧,是base64,但这不算在内)。

你也应该使用一个更具体的Authscope而不是依靠AuthScope .ANY_HOSTAuthScope.ANY_PORT在你的榜样等。

以上是 HttpClientBuilder基本身份验证 的全部内容, 来源链接: utcz.com/qa/432065.html

回到顶部