最近做项目需要使用HttpClient发送Restful请求,其中我们访问的网站是需要进行用户名和密码认证的,http认证的方式不一样,我们使用HttpClient发送请求的方式也不一样。在介绍HttpClient认证方式之前,先介绍一下HttpClient发送Restful请求。
1.什么是Restful请求
简单的说,就是我们访问的资源(可以是一个uri)是一个名词,用http的动词delete,update,post,get等去模拟对资源的CRUD操作。想要了解更多可以参考Restful API设计指南
2.发送Get请求
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class TestGet {
public static void main(String[] args) throws IOException {
//1.创建一个HttpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//2.生成一个get请求
HttpGet httpGet = new HttpGet("http://blog.csdn.net/hzt_fighting_up/article/details/78754878");
//3.执行get请求并返回结果
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
//4.将结果封装为一个对象
HttpEntity httpEntity = httpResponse.getEntity();
//将对象转化为字符串
String resut = EntityUtils.toString(httpEntity);
System.out.println("result: " + resut);
}
}
注解讲的比较清楚了。生成的get请求类似于spring中的@RequestMapping(value="uri", method=RequestMethod.GET)
本来是想拿到简书上的内容的,结果给我抛了个403,授权但是禁止访问,只能get下csdn中的内容了
<head><title>403 Forbidden</title></head>
3.发送Post请求并进行认证
有这样一个业务场景:
1)登陆一个网站(需要用户名和密码)
2)登陆成功以后需要往页面表单中填写信息
3)提交表单
这里会暴露给我们一个提交表单的url
下面用HttpClinet发送post请求实现这个场景
url/userame/password均省略掉
public class TestPost {
public static void main(String[] args) throws IOException {
//1.创建一个HttpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//2.传递的表单信息,以键值对方式
Map<String, String> map = new HashMap<>();
map.put("field1", "name1");
map.put("field2", "name2");
Payload payload = Payload.builder().serviceName("serviceName").keyValues(map).build();
//将最终需要传递的对象转化为StringEntity
StringEntity entity = new StringEntity(Json.encode(payload));
//3.创建一个post请求
HttpPost httpPost = new HttpPost("http://xxxxxx");
//设置要传递的对象
httpPost.setEntity(entity);
//项目中的http的认证方式为抢先式,在header中设置用户名和密码
httpPost.setHeader("username", "xxxx");
httpPost.setHeader("password", "xxxx");
httpPost.setHeader("Content-Type", "application/json");
//4.发送post请求
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
//5.省略对返回结果的操作,可以参考get请求
}
@Builder
@Data
public static class Payload {
private String serviceName;
private Map<String, String> keyValues;
}
}
Payload并不是所有post请求都需要的,得看需求。
抢先式认证方式在发送url的时候直接将用户名密码存放在header中。抢先式认证方式和HTTP Basic Authentication(基本认证方式)有点相似
基本认证方式:
1)client通过url访问server
2)server抛给client一个401错误
3)client输入用户名和密码,用户名和密码会进行一个BASE64编码,到服务端进行解码,匹配数据库
4)成功200,失败继续抛个401
如果是基于基本认证的,则代码需要修改成:
httpPost.setHeader("Authentication", "Basic "
+ Base64.getEncoder().encodeToString("xxxx:xxxx".getBytes()));
用户名和密码必须以username:password
进行编码
4.几种认证方式
1)抢先式认证
2)HTTP Basic Authentication(基本认证)
未进行加密,是不安全的
3)HTTP Digest Authentication(摘要认证)
摘要认证方式和基本认证方式也是差不多的,都需要输入用户名和密码,并且用户名和密码都是保存在浏览器内存中的。主要区别是基本认证对用户名和密码做base64编码是不安全的,而摘要认证采用一种NONCE随机字符串,用户的每次认证都需要哈希和MD5(用户名和密码),并加入这个盐值,客户端和服务器端每次的NONCE都是不一样的,这样就保证了认证的安全性和不可重放性。这里的NONCE并不是Session保存的一个字符串,这样就违背了无状态性特性。服务器端需要为产生的NONCE建一个表记录每个NONCE使用的次数,当然每个只能使用一次,一旦使用两次或多次就认证不通过。总结一下就是MD5加密,较为安全
4)HTTP Client Authentication(客户端认证)
5)Form Based Authentication
基于表单的认证方式超级常见,通过表单提交用户名和密码进行认证
6)Token认证
网友评论