从零开始手写一个http-basic认证服务器

本文详细介绍了HTTP的基本认证(http-basic)和摘要认证(http-digest)的工作流程,包括它们的优缺点。http-basic认证中,用户名和密码以Base64编码形式传输,易被截获,需要配合HTTPS确保安全。http-digest认证通过更复杂的加密过程提高了安全性,减少了明文传输的风险,但流程相对复杂。文章还提供了相关代码示例以加深理解。
摘要由CSDN通过智能技术生成

简单了解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, 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值