一、鉴权原理
1)onvif的用户验证,是基于WS_UsernameToken,所谓的WS_UsernameToken加密,就是将用户名、密码、Nonce、Created都包含在了header里面
参数 | 意义 |
---|---|
username | 待认证的用户名 |
Nonce | 客户端随机产生的字符串 |
Created | 请求认证的UTC时间(格式: 2023-11-29T08:05:52Z) |
PasswordDigest | 需要Password(明文密码)、Nonce、Created经过公式生成 |
2)鉴权信息包括用户名、密码,在HTTP传输过程中不能是明文,有一定的加密算法
Digest鉴权是一种比基本鉴权更安全的身份验证方式,它避免了密码在网络中的明文传输
在ONVIF中,客户端使用用户名和密码的哈希值进行鉴权,服务器通过验证这个哈希值来确认身份
Digest的获取需要移植Base64编解码库、SHA1库,移植完成通过下面公式得到:
- PasswordDigest= B64Encode( SHA1(B64DECODE(Nonce) + Created + Password(明文密码))
Nonce是一个随机数,主要用于防止重放攻击,但是它是经过Base64编码后作为字符串传输的,加密过程中,需要将Nonce解码为二进制数据,然后与Created和Password进行拼接
因此,需要先使用B64DECODE对Nonce进行解码,将其转换为二进制数据
3)有很多onvif接口在调用之前需要鉴权(即调用soap_wsse_add_UsernameTokenDigest函数),并且鉴权完一次之后还需要重新鉴权
成功认证后,可以通过调用ONVIF提供的各种服务接口,如获取设备信息、设置配置、控制摄像头等
只有以下接口是可以在不认证的情况下调用
- GetWsdlUrl
- GetServices
- GetServiceCapabilities
- GetCapabilities
- GetHostname
- GetSystemDateAndTime
- GetEndpointReference
- GetRelayOutputOptions
二、如何认证
可利用gSOAP源码中的soap_wsse_add_UsernameTokenDigest函数,可以轻松实现鉴权
1)在soapcpp2 生成ONVIF代码框架之前,要在onvif.h头文件开头加入:
|
2)依赖
包含以下文件:
- wsseapi.c
- wsseapi.h
- mecevp.c
- mecevp.h
- smdevp.c
- smdevp.h
- threads.c
- threads.h
- dom.c
这些文件在gsoap目录和gsoap/plugin目录下,将这些文件拷贝到项目中,以便参与编译
3)makefile中必须添加编译开关-DWITH_DOM -DWITH_OPENSSL
4)安装OpenSSL
wsse系列函数依赖OpenSSL库,得去OpenSSL官网下载源代码来编译、安装,里面有我们需要的库文件和头文件,如libssl.so、libcrypto.so
5)实现认证
ONVIF_SetAuthInfo函数是对soap_wsse_add_UsernameTokenDigest的二次封装
ONVIF_GetDeviceInformation函数内部增加了设置鉴权信息,在调用soap_call___tds__GetDeviceInformation之前,先调用ONVIF_SetAuthInfo函数设置鉴权信息
|
注意:但凡是ONVIF规定要鉴权的接口,每次调用之前,都要重新设置一次鉴权信息(即调用ONVIF_SetAuthInfo函数),因为IPC的应答信息会重置soap对象,导致鉴权信息丢失,所示每次都要重新设置鉴权信息
三、ONVIF Device Test Tool
1)先使用ONVIF Device Test Tool熟悉鉴权流程
搜索到设备之后需要输入设备用户名User Name及密码Password,后Check
若认证成功Scopes框弹出设备信息,Check这一步不一定要走,只是为了验证用户名或密码是否错误,但是User Name及密码Password若要进行鉴权需要填写,ONVIF Device Test Tool后续的操作会依赖这些输,入用户名及密码后,进入Debug界面
2)进入Debug界面后Authentication栏选择WS-Username token认证,继续点击Media栏,获取Media URL,ONVIF Device Test Tool需要先进行Media URL才能继续获取Media Profile。
需要优先获取到Media URL媒体服务地址,才能进行下一步,不正确的Media URL会导致获取Media Profile失败,获取Media Profile需要进行WS-Username token鉴权认证。
请求发送后右边边框会弹出响应消息,认证成功后Media Profile框下就会有TestMediaProfile(),当中可以选择Profile_x(不同Profile token对应不同码流),Profile_x主要作用在之后RTSP流获取
四、相关函数
|
- soap_wsse_add_UsernameTokenText() 函数通过在SOAP请求中添加WS-Security的用户名令牌(Username Token)和密码来实现认证
涉及到内存分配、数据初始化和设置密码的过程,确保 UsernameToken 和 Password 被正确配置,以便用于认证
- soap_wsse_add_UsernameTokenDigest_at() 函数为SOAP消息添加了包含Digest认证的用户名令牌
包括生成和编码 nonce、计算Digest、设置用户名令牌的各个字段,涉及生成安全认证所需的各种参数,并将它们正确地插入到SOAP请求中
- soap_wsse_add_UsernameTokenDigest() 函数简化了 soap_wsse_add_UsernameTokenDigest_at() 的调用,默认使用当前时间生成用户名令牌的Digest认证
这使得调用者无需手动传入时间戳,简化了函数的使用
|