Onvif开发之客户端鉴权获取参数篇

本文档详细介绍了在ONVIF协议下,客户端如何在发现设备后进行鉴权操作以获取设备参数。鉴权过程简单,通过特定接口完成。成功鉴权后,客户端能正常获取设备能力值。开发中应注意搜索端口限制、内存分配清理、token使用以及ONVIF开发的重复性工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          

 前面一篇已经介绍了客户端如何发些设备,下面这篇简单介绍下在发现设备后,如何通过ONVIF协议来获取设备的相关参数

ONVIF中不管是客户端还是设备端,最先实现的接口都是关于能力的那个接口,在客户端实现的函数名也就是[soap_call___tds__GetServiceCapabilities]通过获取的接口才知道设备具有那些能力,能够进行那些操作,服务端最基本的也需要实现这接口,让客户端知道设备支持那些基本操作。但是当设备端作了加密处理的话,即使你实现了这些接口,也不能正常获取到参数的,所以需要在获取设备参数之前,每次都需要作鉴权处理,这也是为什么我在前篇搜索的例程中把ONVIF_Initsoap这个接口函数里面的操作单独用一个函数接口来完成的原因。下面,我们就需要在这个接口函数里处理鉴权的问题了首先ONVIF鉴权是有两种方式的,一种是通过实现soap_wsse_add_UsernameTokenDigest函数,然后又实现soap_wsse_add_UsernameTokenText等一些复杂的函数接口,我第
<think>好的,用户想了解ONVIF协议机制和实现方法。首先,我需要回忆一下ONVIF协议的基本知识。ONVIF是基于Web Services的,所以机制应该与WS-Security相关。记得ONVIF使用SOAP协议进行通信,而通常涉及用户名和密码的加密传输。 接下来,的具体实现方式。可能需要使用WS-UsernameToken规范,将用户名、密码、Nonce和Created时间戳组合起来,然后进行哈希处理,通常是SHA-1。这样生成的Digest和Nonce一起发送,确保安全性。同时,时间戳用于防止重放攻击,所以服务器端需要验证时间戳的有效性。 然后,用户可能需要示例代码。根据引用中的代码片段,比如引用3中的与安全机制部分,可能需要使用gSOAP工具生成存根,并在请求头中添加UsernameToken。示例代码应该包括如何设置soap上下文,添加安全头,填充用户名、密码等信息,并处理可能的错误。 还要考虑不同场景下的需求,比如设备发现、获取能力、获取视频流等操作都需要。引用5提到设置用户信息用于认证,所以在客户端需要维护这些信息,并在每次请求时附加头。 另外,引用4提到的NTP校时可能影响时间戳的同步,中的时间戳需要与服务器时间一致,否则可能导致失败。因此,校时机制也是成功的一个因素。 最后,需要总结流程,并给出常见问题的解决方法,比如如何处理认证失败,如何应对时间不同步等。同时,生成相关问题,帮助用户进一步学习,比如加密算法、动态、错误处理等。</think>### ONVIF协议机制及实现方法 #### 一、机制核心原理 ONVIF协议基于WS-Security规范实现,采用**UsernameToken**模式,包含以下要素: 1. **用户名/密码**:设备预设的管理员凭证 2. **Nonce**:随机数防止重放攻击,格式为Base64编码的16字节随机值 3. **Created**:UTC时间戳(ISO 8601格式) 4. **PasswordDigest**:通过$SHA1(Nonce + Created + Password)$生成的摘要值[^2][^3] #### 二、实现步骤分解 1. **协议协商**:通过`GetCapabilities`获取设备支持的方式 2. **安全头构造**:在SOAP请求头中插入`<wsse:Security>`节点 3. **参数生成**: ```cpp // 生成Nonce示例 unsigned char nonce[16]; RAND_bytes(nonce, sizeof(nonce)); std::string nonce_base64 = base64_encode(nonce, sizeof(nonce)); // 生成PasswordDigest std::string combined = nonce_str + created_time + password; unsigned char digest[SHA_DIGEST_LENGTH]; SHA1((const unsigned char*)combined.c_str(), combined.length(), digest); std::string password_digest = base64_encode(digest, SHA_DIGEST_LENGTH); ``` #### 三、完整代码示例(基于gSOAP) ```cpp #include "wsseapi.h" // 创建安全头 struct soap *soap = soap_new(); soap_wsse_add_Security(soap); // 设置用户名令牌 if (soap_wsse_add_UsernameTokenDigest(soap, "Auth", username.c_str(), password.c_str())) { // 错误处理 } // 发送请求示例(获取设备信息) _tds__GetDeviceInformation dev_info; _tds__GetDeviceInformationResponse dev_info_resp; DeviceBindingProxy proxy(soap); if (proxy.GetDeviceInformation(&dev_info, dev_info_resp) == SOAP_OK) { // 处理响应 } else { // 处理失败(soap->error) } ``` #### 四、关键实现细节 1. **时间同步**:设备与服务端时间差需在1分钟内[^4],可通过NTP校时保证 2. **错误处理**: - `401 Unauthorized`:凭证错误 - `403 Forbidden`:限不足 - `408 RequestTimeout`:时间戳过期 3. **安全增强**: - 强制使用HTTPS传输 - 定期更新密码 - 限制错误尝试次数 #### 五、典型应用场景 1. 设备发现时的(`Probe`响应) 2. 获取视频流地址(`GetStreamUri`) 3. 云台控制指令(`PTZ`操作) 4. 系统配置修改(如网络参数设置)[^5]
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

max_min_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值