Onvif协议学习:7、鉴权认证


文章目录

  • Onvif协议学习:7、鉴权认证
    • 1、前言
    • 2、ONVIF哪些接口需要认证
    • 3、如何认证
    • 4、安装OpenSSL
    • 5、实现认证
    • 6、特别注意

原文链接:https://blog.csdn.net/benkaoya/article/details/72477536

1、前言

接着上一篇文章接续,上篇文章说到,在测试ONVIF标准的GetDeviceInformation接口时,有些IPC要求鉴权(认证),有些IPC不需要。其实总结起来应该是这样:

  • ONVIF规定,有些接口需要鉴权,有些接口不需要鉴权(在哪里查询等下会说明)。ONVIF规定GetDeviceInformation接口是需要鉴权的。

  • 市面上的IPC摄像头,特别是山寨货,并没有严格按ONVIF规范执行,造成对于有的IPC,客户端不携带鉴权信息也能成功调用GetDeviceInformation接口。

2、ONVIF哪些接口需要认证

辣么,问题来了,哪些ONVIF接口需要鉴权,哪些不需要鉴权,在哪里可以查看呢?答案是,在官网的ONVIF Core Specification文档中有详细的规定,如Version 16.12的版本为《ONVIF-Core-Specification-v1612.pdf》。在该文档的「Access classes for service requests」章节中有接口访问权限的相关规定,如下图所示。比如「PRE_AUTH」的规定是:The service shall not require user authentication,那非「PRE_AUTH」的就是都要认证的。

拿GetServices接口举个例子,在ONVIF Core Specification文档中找到GetServices接口定义(如下图所示),会有Access Class: PRE_AUTH的说明,表明客户端调用该接口时,不需要携带用户名、密码认证信息。

再看看GetDeviceInformation接口规定(如下图所示),Access Class: READ_SYSTEM,说明客户端调用该接口是需要进行认证。

3、如何认证

这里的鉴权信息包括用户名、密码,在HTTP传输过程中不能是明文,有一定的加密算法。

如果你整不清楚这个加密算法怎么回事,那么,我推荐利用gSOAP源码中的soap_wsse_add_UsernameTokenDigest函数,可以轻松实现鉴权。要使用该函数,需要注意以下几点:

  • 就像专栏前面文章提到过的一样,要使用soap_wsse_add_UsernameTokenDigest函数进行授权,在soapcpp2 生成ONVIF代码框架之前,要在onvif.h头文件开头加入:
#import “wsse.h”
  • 依赖gSOAP中的这些源码:wsseapi.c、wsseapi.h、mecevp.c、mecevp.h、smdevp.c、smdevp.h、threads.c、threads.h、dom.c,这些文件在gsoap目录和gsoap/plugin目录下,将这些文件拷贝到你的项目中,以便参与编译。

  • 在加入上面说的.c和.h文件后,结果编译失败,提示找不到「openssl/evp.h」文件:

smdevp.h(54): fatal error C1083: 无法打开包括文件:“openssl/evp.h”: No such file or directory

究其原因,wsse系列函数依赖OpenSSL库,我们得去OpenSSL官网下载源代码来编译、安装,里面有我们需要的库文件和头文件。

4、安装OpenSSL

如果你是跟着我专栏在学习,在专栏前面文章「使用gSOAP生成ONVIF框架代码」中,已经安装过OpenSSL了,对于还没安装OpenSSL的,可以参考那篇文章如何安装。

5、实现认证

代码如下,重点在ONVIF_SetAuthInfo函数(是对soap_wsse_add_UsernameTokenDigest的二次封装),相比于上一篇文章,这次的ONVIF_GetDeviceInformation函数内部,增加了设置鉴权信息,在调用soap_call___tds__GetDeviceInformation之前,先调用ONVIF_SetAuthInfo函数设置鉴权信息。

你可以拿一个需要鉴权的IPC来测试,通过开启、关闭ONVIF_SetAuthInfo语句,来观察效果。注意:你要是拿一个本就不需要鉴权的IPC,是测不出预期效果的。

#define USERNAME    "admin"
#define PASSWORD    "admin"/************************************************************************
**函数:ONVIF_SetAuthInfo
**功能:设置认证信息
**参数:[in] soap     - soap环境变量[in] username - 用户名[in] password - 密码
**返回:0表明成功,非0表明失败
**备注:
************************************************************************/
static int ONVIF_SetAuthInfo(struct soap *soap, const char *username, const char *password)
{int result = 0;SOAP_ASSERT(NULL != username);SOAP_ASSERT(NULL != password);result = soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);SOAP_CHECK_ERROR(result, soap, "add_UsernameTokenDigest");EXIT:return result;
}/************************************************************************
**函数:ONVIF_GetDeviceInformation
**功能:获取设备基本信息
**参数:[in] DeviceXAddr - 设备服务地址
**返回:0表明成功,非0表明失败
**备注:
************************************************************************/
int ONVIF_GetDeviceInformation(const char *DeviceXAddr)
{int result = 0;struct soap *soap = NULL;struct _tds__GetDeviceInformation           devinfo_req;struct _tds__GetDeviceInformationResponse   devinfo_resp;SOAP_ASSERT(NULL != DeviceXAddr);SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);memset(&devinfo_req, 0x00, sizeof(devinfo_req));memset(&devinfo_resp, 0x00, sizeof(devinfo_resp));result = soap_call___tds__GetDeviceInformation(soap, DeviceXAddr, NULL, &devinfo_req, &devinfo_resp);SOAP_CHECK_ERROR(result, soap, "GetDeviceInformation");dump_tds__GetDeviceInformationResponse(&devinfo_resp);EXIT:if (NULL != soap) {ONVIF_soap_delete(soap);}return result;
}

用大华IPC进行测试,执行结果如下:

================= + dump_tds__GetDeviceInformationResponse + >>>
Manufacturer:       Dahua
Model:              IPC-HDW1025C
Serial Number:      2K04788PAA00441
Hardware Id:        1.00
Firmware Version:   2.420.Dahua 00.14.R, build: 2016-06-18
================= - dump_tds__GetDeviceInformationResponse - <<<

6、特别注意

需要特别、特别、特别注意的是:但凡是ONVIF规定要鉴权的接口,每次调用之前,都要重新设置一次鉴权信息(即调用ONVIF_SetAuthInfo函数),哪怕你之前已经设置过鉴权信息了,否则后续调用ONVIF接口依然会报错。

我们来做个测试,连续两次调用soap_call___tds__GetDeviceInformation接口,第一次调用之前有设置鉴权信息,第二次调用之前没有设置鉴权信息,代码如下:

int ONVIF_GetDeviceInformation2(const char *DeviceXAddr)
{int result = 0;struct soap *soap = NULL;struct _tds__GetDeviceInformation           devinfo_req;struct _tds__GetDeviceInformationResponse   devinfo_resp;SOAP_ASSERT(NULL != DeviceXAddr);SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));/* 第一次调用soap_call___tds__GetDeviceInformation之前有设置鉴权信息 */ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);memset(&devinfo_req, 0x00, sizeof(devinfo_req));memset(&devinfo_resp, 0x00, sizeof(devinfo_resp));result = soap_call___tds__GetDeviceInformation(soap, DeviceXAddr, NULL, &devinfo_req, &devinfo_resp);SOAP_CHECK_ERROR(result, soap, "GetDeviceInformation");dump_tds__GetDeviceInformationResponse(&devinfo_resp);/* 第二次调用soap_call___tds__GetDeviceInformation之前没有设置鉴权信息,导致调用失败 */memset(&devinfo_req, 0x00, sizeof(devinfo_req));memset(&devinfo_resp, 0x00, sizeof(devinfo_resp));result = soap_call___tds__GetDeviceInformation(soap, DeviceXAddr, NULL, &devinfo_req, &devinfo_resp);SOAP_CHECK_ERROR(result, soap, "GetDeviceInformation");dump_tds__GetDeviceInformationResponse(&devinfo_resp);EXIT:if (NULL != soap) {ONVIF_soap_delete(soap);}return result;
}

同样用大华IPC进行测试,执行结果如下,第二次调用soap_call___tds__GetDeviceInformation失败:

================= + dump_tds__GetDeviceInformationResponse + >>>
Manufacturer:       Dahua
Model:              IPC-HDW1025C
Serial Number:      2K04788PAA00441
Hardware Id:        1.00
Firmware Version:   2.420.Dahua 00.14.R, build: 2016-06-18
================= - dump_tds__GetDeviceInformationResponse - <<<[soap] GetDeviceInformation error: 401, is internal, HTTP Error

之所以会如此,究其根源,是因为IPC的应答信息会重置soap对象,导致鉴权信息丢失,所示每次都要重新设置鉴权信息。

Onvif协议学习:7、鉴权认证相关推荐

  1. js获取session_学习后端鉴权系列: 基于Cookie, Session认证

    说起鉴权大家应该都很熟悉, 不过作为前端开发来讲, 鉴权的流程大头都在后端小哥那边, 但是作为一个有志气的开发者肯定要好好学习整个鉴权流程以及方案, 不然怎么跟后端合作. 常见的鉴权方案 基于Cook ...

  2. Onvif协议学习:14、球机云台控制PTZ

    Onvif协议学习:14.球机云台控制PTZ 文章目录 Onvif协议学习:14.球机云台控制PTZ 一.介绍 二.代码实现 八个方向.放下及缩小控制 聚焦控制 原文链接:https://blog.c ...

  3. js如何获取jwt信息_学习后端鉴权系列: 基于JWT的会话管理

    内容回顾 上一节讲了基于Cookie+Session的认证方案. Even:学习后端鉴权系列: 基于Cookie, Session认证​zhuanlan.zhihu.com 由于基于Session方案 ...

  4. aka鉴权 ims_ims 注册鉴权认证过程

    移动通信的安全问题正越来越多地受到关注.2G网络主要传输语音业务,采用的是单向的用户认证方案,即网络能够验证用户身份是否合法,而用户无法确认其所连接的网络服务是否可靠.然而,3G网络将会演变成一个覆盖 ...

  5. MGCP /H.248 鉴权认证

    MGCP /H.248 鉴权认证 MGCP /H.248 鉴权认证 鉴权概述和基本算法 MGCP/H.248鉴权概述 MGCP协议没有涉及安全认证的标准.对于网络应用终端客户或运营商来说都不安全的盗号 ...

  6. ims 注册鉴权认证过程

    摘要:IP多媒体子系统(IMS)作为3G网络的核心控制平台,其安全问题正面临着严峻的挑战.IMS的接入认证机制的实现作为整个IMS安全方案实施的第一步,是保证IMS系统安全的关键.基于认证和密钥协商( ...

  7. Onvif协议学习:1、Onvif与Onvif Profile协议基本概念

    Onvif协议学习:1.Onvif与Onvif Profile协议基本概念 文章目录 Onvif协议学习:1.Onvif与Onvif Profile协议基本概念 1.ONVIF 2.Onvif Pro ...

  8. Onvif协议学习:13、遮挡报警

    Onvif协议学习:13.遮挡报警 文章目录 Onvif协议学习:13.遮挡报警 1.原理简介 (1).Basic Notification (2).Pull-Point Notification 2 ...

  9. Python 技术篇-百度语音API鉴权认证获取Access Token实例演示

    百度语音官方鉴权认证文档 下面来为大家进行鉴权认证获取Access Token的演示: 首先需要创建自己的个人语音应用,在应用列表里进行创建. 百度语音个人应用列表 然后用这个应用里的 API Key ...

最新文章

  1. vs2010设置boost开发环境
  2. 收藏 | 使用Mask-RCNN在实例分割应用中克服过拟合
  3. Java——DOM4J生成XML
  4. 登录MySQL数据库
  5. high speed train is awesome
  6. iscsiadm及其他磁盘相关命令
  7. spring boot——MockMvc的用法 (SpringBoot 1.5.18)下测试通过
  8. plt.plot绘图
  9. Linux下l2tp客户端xl2tpd安装配置的具体操作
  10. 神经网络绘图软件推荐合集
  11. 计算字符串占用字节数
  12. 关于勒索病毒 Ransom:Win32.WannaCrypt 解决方案的最后一次说明
  13. hive-创建数据库-创建表--hive版本3.1.2
  14. [软考]挣值管理EVM详细解释及应用,实例讲解收集(信息系统项目管理师-成本管理)...
  15. 网站漂浮广告代码收藏
  16. 奥赛金牌计算机博士中学老师,20位新老师19位是清北硕博,这所中学火了!简历曝光!...
  17. 大数据训练营课程大纲项目简介
  18. node用mongodb还是mysql,Node 操作 mongoDB 数据库和 mySQL数据库
  19. 通过Stream流找出集合中对象中某个属性重复的值.
  20. 课堂笔记:Android UI控件

热门文章

  1. 图注意力网络的代码下载和分析
  2. 培训班面试一个月入职了一家外包公司(谈谈感悟)
  3. 在京东待了几年,感觉自己废了····
  4. 2022-2027(新版)中国数字隔离器行业销售态势与需求前景预测报告
  5. K8S容器云平台查询容器TOP真实使用情况工具之Topic
  6. 什么是DUNS商业信用报告?
  7. SQL Server系统数据库损坏时的快速恢复使用
  8. revit链接文件操作
  9. K8S 自动部署工具
  10. esxi虚拟化服务器端口聚合,配置ESXi的端口聚合.docx