有关HTTP 401验证的那些事儿

        前段时间突然遇到有一个需求:要求能够抓取到NVR上连接的摄像头设备列表。

        因为要的比较急,而且我还没啃透海康SDK的文档,所以只好考虑另辟蹊径,用一些别的方法来达到目标咯。

        我们登录到NVR的web控制页面不难发现,左侧可不就是我想要的设备列表吗!?

那么,问题来了,我要怎么搞到这一块的数据呢?

        打开F12开发者工具,我们可以观察到浏览器发送了哪些请求,并接收到了哪些服务器响应的数据,经过筛查,我发现了有一个浏览器发起的请求,请求到的结果似乎就是我想要的东西。

        我们把这个请求的URL复制出来,单独观察看看:

http://192.168.0.109/ISAPI/ContentMgmt/InputProxy/channels?security=1&iv=decb6a649cd7e051546206bdd6159c98

        通过观察这个URL地址,可以发现这里请求的NVR的ip是:192.168.0.109,NVR开放的端口是:80,

请求的资源是:/ISAPI/ContentMgmt/InputProxy/channels

请求时还带了几个参数:security和iv。至于这两个参数是啥意思,我还不知道。

        但是本着“删繁就简”的原则,我可以去测试一下这些参数。

        首先把URL粘贴进浏览器中,我们手动发起访问,看看是个什么结果:

访问结果是网页弹出了一个简易的认证页面,要求你输入账号和密码才能登录。

        在我们输入了正确的账号和密码之后,这个地址显示出了一份包含了所有设备的xml:

当我输入错误的账号密码或者点击“取消”时,则会返回一份提示401错误的xml:

 

 

        经过几轮测试,我发现前面说到的请求带的两个参数:security和iv,即使删掉也能够正常地获取到xml。那么我需要请求的URL地址就简化成了:

http://192.168.0.109/ISAPI/ContentMgmt/InputProxy/channels

        到目前为止,我遇到的问题就简化成了:如何抓取到上面这个URL下的xml,并且解析出设备列表。解决这个问题的小目标也明确了:

1、模拟登陆这个网页,然后获取到xml;

2、解析xml,拿到所需要的设备信息。

 

        首先咱先可以完成第一个小目标,模拟登陆这个网页。

        电视机前有心的小朋友肯定注意到了,上面截图中,弹出的这个认证页面和一般账号密码form是很不一样的,它比较简陋,而且是浏览器主动弹出来的,不是显示在页面上的。这其中究竟发生了什么呢?

        我们可以抓个包来看看。(因为chrome的开发者工具抓到的包比较简陋,分析不出啥有用的信息,所以我就用Fiddler抓包了。)

        再使用浏览器完成了一次请求之后,我们轻而易举地在Fiddler里面发现抓到了两个包:

        第一个响应码为401的数据包里面的报文信息是这样的:

        上图中蓝色的部分为服务器返回的,提示需要认证的信息(因为http 401代码表示你未授权,因此需要验证你的身份信息),这里我们可以发现服务器提供了两种认证算法方式:基本(Basic)认证和摘要(Digest)认证。

        然后再看我们在输入正确的账号和密码之后,浏览器发出的数据包(就是下面那个状态码是200的):

不难发现,数据包中包含了一项很特别的参数:Authorization。浏览器发送的这个数据完整的是这样的:

Digest username="admin", realm="DVRNVRDVS", nonce="b0a97d26d1216728a76f9cc23fdc1917:1547564458637", uri="/ISAPI/ContentMgmt/InputProxy/channels", algorithm=MD5, response="45924b8342669b4493532a8352b628d0", qop=auth, nc=00000001, cnonce="2095e2d3b12ae7ce"

        这里需要先补充一下HTTP 401认证的一些基本知识,特别是其中摘要(Digest)算法的知识:认证模式之Digest模式 

以及 digest 用户认证 response生成算法

        这些都了解了之后。那么剩下的问题也就不难了:我们按照标准的digest算法,计算出正确的数据,并且把它发送给服务器,那不就认证通过啦?

        这里我用Java写了一个能计算出正确Response值且能完成自动登录并拿到xml的demo。代码这里不多赘述,这里仅说明一下关键的步骤和原理:

严格按照Digest算法的计算步骤算各项MD5值,且每一项都要取小写字符(大写字符算出来的MD5值不一样),那么最后算出来的Response值便是正确的MD5值。

        然后我们重写toString()方法,把计算出来的结果,格式化为标准的Digest header格式:

        最后我们将计算出来的结果放在http请求的header中,发送给服务器,应该就能验证通过了。

        测试一下,能拿到数据。

     

        至于最后的解析我用的是dom4j。这个不复杂,在这里就不多赘述了。

 

        最后附上这个小demo:模拟Digest认证的登录demo

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值