HttpClient 4 - 实现HTTP摘要认证
什么是摘要认证
说到摘要认证(Digest authentication
)就不得不提基本认证(Basic authentication
),在RFC2617中有关于它的描述,摘要认证是一种基于挑战-应答模式的认证模型,用于在HTTP报文交互中,服务端确认客户端身份。
两者具体表现形式是一样的,都是直接访问某个地址,会弹出一个要求用户输入用户名和密码的对话框,只有用户名和密码匹配才能继续访问,摘要认证比基本认证更加安全。
更多摘要认证和基本认证的信息:48.HTTP基本认证与摘要认证
用DefaultHttpClient实现
在HttpClient 4.3
以前,DefaultHttpClient
还没有被Deprecated
的时候是没有问题的,实现也很简单:
package com.xx.xx.utils;
import com.sun.istack.internal.Nullable;
import org.apache.commons.lang.StringUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.auth.DigestSchemeFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import javax.validation.constraints.NotNull;
import java.util.Collections;
/**
* Create by IntelliJ IDEA
*
* @Author chenlei
* @DateTime 2018/7/11 17:00
* @Description DigestHttpClientUtil
*/
public class DigestHttpClientUtil {
public static void main(String[] args){
HttpClient defaultHttpClient = httpClient();
HttpClient digestHttpClient = digestHttpClient("stats","stats",null,null);
HttpGet httpGet = new HttpGet("http://192.168.20.8:6080/");
try {
System.out.println("=============no auth=====================");
System.out.println(EntityUtils.toString(defaultHttpClient.execute(httpGet).getEntity()));
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println("=============digest auth=====================");
System.out.println(EntityUtils.toString(digestHttpClient.execute(httpGet).getEntity()));
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
public static HttpClient digestHttpClient(@NotNull String username, @NotNull String password, @Nullable String host, @Nullable Integer port){
DefaultHttpClient httpClient = new DefaultHttpClient();
Credentials credentials = new UsernamePasswordCredentials(username,password);
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(StringUtils.isBlank(host) ? AuthScope.ANY_HOST : host, port == null ? AuthScope.ANY_PORT : port),
credentials
);
httpClient.getParams().setParameter(AuthSchemes.DIGEST, Collections.singleton(AuthSchemes.DIGEST));
httpClient.getAuthSchemes().register(AuthSchemes.DIGEST,new DigestSchemeFactory());
return httpClient;
}
public static HttpClient httpClient(){
return new DefaultHttpClient();
}
}
output:
=============no auth=====================
<html><head><title>ProxySQL status page</title></head><body>Access denied</body></html>
=============digest auth=====================
<!DOCTYPE html><head>
<title>ProxySQL Home</title>
...
HttpClient 4.3 实现
HttpClient 4.3
以后,DefaultHttpClient
已经被列为过时,所以有更好的实现方式:
package com.xx.xx.utils;
import com.sun.istack.internal.Nullable;
import org.apache.commons.lang.StringUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.auth.DigestSchemeFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.validation.constraints.NotNull;
import java.util.Collections;
/**
* Create by IntelliJ IDEA
*
* @Author chenlei
* @DateTime 2018/7/11 17:00
* @Description DigestHttpClientUtil
*/
public class DigestHttpClientUtil {
public static void main(String[] args){
HttpClient defaultHttpClient = httpClient();
HttpClient digestHttpClient = digestHttpClient("stats","stats",null,null);
HttpGet httpGet = new HttpGet("http://192.168.20.8:6080/");
try {
System.out.println("=============no auth=====================");
System.out.println(EntityUtils.toString(defaultHttpClient.execute(httpGet).getEntity()));
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println("=============digest auth=====================");
System.out.println(EntityUtils.toString(digestHttpClient.execute(httpGet).getEntity()));
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
public static HttpClient digestHttpClient(@NotNull String username, @NotNull String password, @Nullable String host, @Nullable Integer port){
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(StringUtils.isBlank(host) ? AuthScope.ANY_HOST : host, port == null ? AuthScope.ANY_PORT : port),
new UsernamePasswordCredentials(username,password));
return HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build();
}
public static HttpClient httpClient(){
return HttpClients.custom().build();
}
}
output:
=============no auth=====================
<html><head><title>ProxySQL status page</title></head><body>Access denied</body></html>
=============digest auth=====================
<!DOCTYPE html><head>
<title>ProxySQL Home</title>
...