HttpClient 4.3 - 实现HTTP摘要认证(Digest authentication)

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>
...
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值