简单了解HTTP
HTTP是英文HyperText Transfer Protocol首字母缩写,是目前WWW万维网通讯标准协议,在属于OSI第七层(应用层)协议,要实现HTTP协议通常需要基于TCP-Socket套接字作为传输层的支撑。
什么是http-basic
http-basic是http协议的认证模块,http-basic也是http协议下的协议。下面先来看一下http-basic协议流程图:
流程图说明:
第一步:当客户端通过浏览器访问实现了http-basic的后端服务器时,后端服务器首先会校验是否携带Authorization请求头,如果没有则返回Code=401:
http.setCode(401);
http.setStatus("Unauthorized");
// 其中Basic表示认证类型为Basic,Realm用来描述后端应用名称,例如OA,CRM,可自定义
// 除了Basic认证类型外,后面还会将另一种类型:Digest
http.setHeader("WWW-Authenticate", "Basic Reaml=\"HTTP Demo Server\"");
下面是谷歌浏览器默认抓包截图:
此时用户就会收到浏览器弹出的登陆输入框:
第二步:当用户输入用户名和密码,点击登陆按钮时,浏览器会将表单的用户名和密码按规则:BASE64(用户名:密码)编码后放到请求头为HTTP-Request-Header=Authorization: Basic cm9vdDoxMjM0NTY= 方式提交给服务器进行认证,具体截图如下:
第三步:后端服务器接收到请求后,仍然会校验是否携带Authorization请求头,如果携带,则通过BASE64解码出来得到用户名:密码字符串,然后通过":"进行分隔得到用户名和密码进行验证,如果验证失败,继续第一步的内容,如果验证成功,后端服务可能会进一步验证URL资源权限等,如果验证资源权限不通过,此时参考第一步的方式返回(注意此时返回Code=403):
http.setCode(401);
http.setStatus("Forbidden");
http.setHeader("WWW-Authenticate", "Basic Reaml=\"HTTP Demo Server\"");
如果验证通过,则返回Code=200即可:
http.setCode(200);
http.setStatus("OK");
http-basic缺陷
http-basic(当响应头WWW-Authenticate:Basic Reaml=xxx)存在以下缺陷:
1、用户名和密码明文(仅仅只是Base64编码而已)传输,需要配合HTTPS来保证信息传输的安全。
2、就算HTTPS将密码加密传输,也仍然存在重放攻击风险。
3、代理和中间节点的防护措施弱,很容易通过伪装服务器来骗过认证,诱导用户输入用户名和密码。
下面将介绍http-basic升级版更为安全的摘要认证http-digest。
了解http-digest流程
http-digest流程比http-basic流程复杂很多,流程图如下:
下面对http-digest涉及的字段作用进行说明:
-
WWW-Authentication:用来定义使用何种方式(Basic、Digest、Bearer等)去进行认证以获取受保护的资源。
-
realm:表示Web服务器中受保护文档的安全域(比如OA、CRM系统域等),用来指示需要哪个域的认证。
-
qop:保护质量,包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略,可以为空,但不推荐为空值。
-
nonce:服务端向客户端发送质询时附带的一个随机数,这个数会经常发生变化。客户端计算密码摘要时将其附加上去,使得多次生成同一用户的密码摘要各不相同,用来防止重放攻击。
-
nc:nonce计数器,是一个16进制的数值,表示同一nonce下客户端发送出请求的数量。例如,在响应的第一个请求中,客户端将发送“nc=00000001”。这个指示值的目的是让服务器保持这个计数器的一个副本,以便检测重复的请求。
-
cnonce:客户端随机数,这是一个不透明的字符串值,由客户端提供,并且客户端和服务器都会使用,以避免用明文文本。这使得双方都可以查验对方的身份,并对消息的完整性提供一些保护。
-
response:这是由用户代理软件计算出的一个字符串,以证明用户知道口令。
-
Authorization-Info:用于返回一些与授权会话相关的附加信息。
-
nextnonce:下一个服务端随机数,使客户端可以预先发送正确的摘要
-
rspauth:响应摘要,用于客户端对服务端进行认证。
-
stale:当密码摘要使用的随机数过期时,服务器可以返回一个附带有新随机数的401响应,并指定stale=true,表示服务器在告知客户端用新的随机数来重试,而不再要求用户重新输入用户名和密码了。
http-digest流程说明
第一步:当客户端通过浏览器访问实现了http-digest的后端服务器时,后端服务器首先会校验是否携带Authorization请求头,如果没有则返回Code=401:
http.setCode(401);
http.setStatus("Unauthorized");
// 其中Basic表示认证类型为Basic,Realm用来描述后端应用名称,例如OA,CRM,可自定义
// 除了Basic认证类型外,后面还会将另一种类型:Digest
http.setHeader("WWW-Authenticate", "Basic Reaml=\"HTTP Demo Server\"");
并且返回(注意和http-basic的区别):
WWW-Authenticate: Digest nonce=MTYyMTA4OTE3MDgyODo6ODQzMjU0NjMwNTE0MTYzNzEy,realm=LazyAgentConsole,qop=auth,algorithm=MD5
下面是谷歌浏览器默认抓包截图:
此时用户就会收到浏览器弹出的登陆输入框:
第二步:当用户输入用户名和密码,点击登陆按钮时,浏览器会将表单的用户名和密码进行加密后放到请求头,浏览器抓包截图如下:
Authorization: Digest username="root", realm="LazyAgentConsole", nonce="MTYyMTA4OTMyNjUyMzo6ODQzMjU1MjgzNTQ2MzI0OTky", uri="/", algorithm=MD5, response="7497e20c827e0de40ac28379ab52afe6", qop=auth,