关于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; } }