ONVIF认证开发疑问:VB.NET下WS-Security及HTTP摘要认证求助
关于ONVIF认证在VB.NET中的实现方案
我完全懂你说的这种头疼的感觉——ONVIF的WS-Security认证确实是个绕不开的坎,尤其是在VB.NET环境下找能用的示例简直像大海捞针。下面针对你的问题逐一解答:
1. HTTP摘要认证 vs WS-Security的适用性
ONVIF标准主要依赖WS-Security的UsernameToken Profile(带密码摘要的版本),而HTTP摘要认证是HTTP层级的认证机制,虽然部分ONVIF设备可能支持,但并非所有设备都兼容,而且不符合ONVIF的标准规范。所以如果要保证兼容性,还是得实现WS-Security的认证逻辑。
2. VB.NET移植C#认证示例的可行性
当然有开发者完成过这项工作!核心思路和C#一致:手动构造SOAP消息中的<Security>头部,包含UsernameToken、随机Nonce、Created时间戳,以及基于Nonce + Created + 密码计算的SHA1摘要。
这里给你一个简化的VB.NET代码片段,用来生成WS-Security头部并注入到WCF请求中:
自定义消息检查器(注入WS-Security头)
Imports System Imports System.ServiceModel Imports System.ServiceModel.Dispatcher Imports System.Security.Cryptography Imports System.Text Public Class OnvifSecurityInspector Implements IClientMessageInspector Private ReadOnly _username As String Private ReadOnly _password As String Public Sub New(username As String, password As String) _username = username _password = password End Sub ' 处理回复(这里不需要额外操作) Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply End Sub ' 发送请求前注入Security头 Public Function BeforeSendRequest(ByRef request As Message, channel As IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest ' 生成随机Nonce和UTC时间戳 Dim nonceBytes As Byte() = New Byte(15) {} Using rng As New RNGCryptoServiceProvider() rng.GetBytes(nonceBytes) End Using Dim nonceBase64 = Convert.ToBase64String(nonceBytes) Dim createdTimestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ") ' 计算密码摘要:SHA1(Nonce + Created + 原始密码) Dim digestInput = nonceBase64 & createdTimestamp & _password Dim digestBytes = New SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(digestInput)) Dim passwordDigest = Convert.ToBase64String(digestBytes) ' 构造SOAP Security头部XML Dim securityXml = $"<wsse:Security xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""> <wsse:UsernameToken> <wsse:Username>{_username}</wsse:Username> <wsse:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"">{passwordDigest}</wsse:Password> <wsse:Nonce EncodingType=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"">{nonceBase64}</wsse:Nonce> <wsu:Created xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">{createdTimestamp}</wsu:Created> </wsse:UsernameToken> </wsse:Security>" ' 将XML转换为MessageHeader并添加到请求中 Dim securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityXml, False) request.Headers.Add(securityHeader) Return Nothing End Function End Class ' 自定义行为类,用来添加消息检查器 Public Class OnvifClientBehavior Implements IEndpointBehavior Public ReadOnly Property MessageInspectors As New List(Of IClientMessageInspector)() Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters End Sub Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior For Each inspector In MessageInspectors clientRuntime.ClientMessageInspectors.Add(inspector) Next End Sub Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior End Sub Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate End Sub End Class
使用示例
' 假设你已经通过ONVIF的WSDL生成了VB.NET客户端(比如OnvifMediaClient) Dim mediaClient As New OnvifMediaClient() Dim securityBehavior As New OnvifClientBehavior() ' 添加认证检查器,替换为你的设备用户名和密码 securityBehavior.MessageInspectors.Add(New OnvifSecurityInspector("admin", "your_device_password")) mediaClient.Endpoint.Behaviors.Add(securityBehavior) ' 接下来就可以正常调用ONVIF接口了 Dim profiles = mediaClient.GetProfiles()
3. 现成的DLL或封装服务
目前没有官方提供的带WS-Security的VB.NET ONVIF库,但有不少开源项目可以参考:
- 一些开发者会把C#的ONVIF客户端库(比如
ONVIF-Device-Manager的核心逻辑)移植到VB.NET,你可以搜索VB.NET ONVIF相关的开源仓库,找到已经封装好WS-Security的实现 - 也可以使用WCF的
ChannelFactory结合上述消息检查器的方式,不需要额外的DLL,纯代码实现认证逻辑
4. 找不到VB.NET示例的原因
确实,VB.NET的ONVIF资源远少于C#,因为大部分开源项目和官方示例都优先用C#。但只要掌握了WS-Security的核心逻辑,移植C#代码到VB.NET是完全可行的——两者的WCF操作逻辑一致,只是语法有差异,重点是构造正确的SOAP Security头部。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

