
关于HTTP BASIC认证
Basic 认证是服务器与客户端之间进行认证的一种方式,最初是在HTTP 1.0 规范(RFC 1945)中定义,后续的有关安全的信息可以在HTTP 1.1规范(RFC 2616)和HTTP认证规范(RFC 2617)中找到。HTTP Basic Authentication认证的服务,需要提供用户名和密码,否则服务器就会返回401。
HTTP BASIC认证流程原理
HTTP使用BASIC认证的原理是在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份认证的方法。
实现方法:当一个客户端向HTTP服务器进行数据请求时,如果客户端未被认证,则HTTP服务器将通过基本认证过程对客户端的用户名及密码进行验证,以决定用户是否合法。客户端在接收到HTTP服务器的身份认证要求后,会提示用户输入用户名及密码, 用户输入后,客户端将用户名和密码中间用“:”分隔合并,并将合并后的字符串用BASE64编码,在每次请求数据 时,将密文附加于请求头(Request Header)Authorization: Basic XXXXXXX中。HTTP服务器在每次收到请求包后,根据协议取得客户端附加的用户信息(BASE64编码的用户名和密码),解开请求包,对用户名及密码进行验证,如果用 户名及密码正确,则根据客户端请求,返回客户端所需要的数据;否则,返回错误代码或重新要求客户端提供用户名及密码。
JAVA HttpClient 4.5.3 抢先认证实例
原HttpClient 4.1.1 实例方法DefaultHttpClient等已过时废弃, 如下测试实例中,实现了两种方法:
1)通过HttpClient提供的抢先认证方式,直接跳过验证是否登录,把Basic Authorization信息发送给服务器
2)直接添加header的方式,HttpClient抢先认证方式原理同理
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Base64;
import org.apache.http.HttpEntity;
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.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
public class HttpsClientTest {
@Test
public void test_auth_basic_should_success() throws Exception {
String url ="http://192.168.1.100:8080/bywei/api/authtest";
HttpHost targetHost = new HttpHost("192.168.1.100", 8080, "http");
HttpGet get = new HttpGet(url);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("test-auth", "=^ad.*sa:_2_RXa*23");
// 使用 AuthCache 方式将使用RestClient 中的 MainClientExec方法,在发送请求时直接携带Authorization header信息
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
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
String content = doExecute(get, targetHost, credentials, localcontext);
System.out.println("Authorization Basic认证authCache请求响应:"+content);
}
@Test
public void test_auth_header_should_success() throws Exception {
String url ="http://192.168.1.100:8080/bywei/api/authtest";
HttpHost targetHost = new HttpHost("192.168.1.100", 8080, "http");
HttpGet get = new HttpGet(url);
String token = "test-auth:=^ad.*sa:_2_RXa*23";
byte[] auth = Base64.getEncoder().encode(token.getBytes("UTF-8"));
get.addHeader("Authorization", "Basic " + new String(auth));
HttpClientContext context = HttpClientContext.create();
String content = doExecute(get, targetHost, null, context);
System.out.println("Authorization Basic认证header请求响应:"+content);
}
private CloseableHttpClient getHttpClient(UsernamePasswordCredentials credentials){
RequestConfig requestConf = RequestConfig.custom().setAuthenticationEnabled(false).build();
HttpClientBuilder httpClientBuilder = HttpClients.custom();
if(credentials != null) {
CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(AuthScope.ANY, credentials);
httpClientBuilder.setDefaultCredentialsProvider(provider);
}
CloseableHttpClient client = httpClientBuilder.setDefaultRequestConfig(requestConf).build();
return client;
}
private String doExecute(HttpGet get, HttpHost targetHost, UsernamePasswordCredentials credentials, HttpContext contenxt) throws Exception {
CloseableHttpResponse response = null;
String content = "";
try {
//指定Client使用HttpContext,包含属性:http.auth.auth-cache
response = getHttpClient(credentials).execute(get, contenxt);
HttpEntity entity = response.getEntity();
if(entity!=null) {
Charset charset = ContentType.getOrDefault(entity).getCharset();
content = EntityUtils.toString(entity, charset);
EntityUtils.consume(entity);
return content;
}
} catch(Exception ie) {
ie.printStackTrace();
throw ie;
} finally {
try {
if(response!=null) {
response.close();
}
} catch(IOException e) {
}
if(get!=null) {
get.releaseConnection();
}
}
return content;
}
}
