C# 无法使用C连接到启用OnVif的摄像头#

C# 无法使用C连接到启用OnVif的摄像头#,c#,wsdl,wireshark,digest-authentication,onvif,C#,Wsdl,Wireshark,Digest Authentication,Onvif,我第一次与IPCams合作,我正在尝试连接到OnVif摄像机。我看过各种论坛和stack overflow,我得到了以下代码。我知道这些代码没有做任何有用的事情,但现在它只是一个概念证明。它会在我的网络上找到所有4个摄像头,然后我手动连接到其中一个,以提取一些信息,例如GetServices 在这个阶段,我得到了400个错误的响应。我已经用WireShark来回查看了流量,就我所知,关于生成的密码,似乎一切都正常(安全和加密根本不是我的领域!) 有人能帮忙或提供建议吗 class Program

我第一次与IPCams合作,我正在尝试连接到OnVif摄像机。我看过各种论坛和stack overflow,我得到了以下代码。我知道这些代码没有做任何有用的事情,但现在它只是一个概念证明。它会在我的网络上找到所有4个摄像头,然后我手动连接到其中一个,以提取一些信息,例如GetServices

在这个阶段,我得到了400个错误的响应。我已经用WireShark来回查看了流量,就我所知,关于生成的密码,似乎一切都正常(安全和加密根本不是我的领域!)

有人能帮忙或提供建议吗

class Program
{

    static void Main(string[] args)
    {
        var endPoint = new UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005);

        var discoveryClient = new DiscoveryClient(endPoint);

        discoveryClient.FindProgressChanged += discoveryClient_FindProgressChanged;

        discoveryClient.FindCompleted += discoveryClient_FindCompleted;

        FindCriteria findCriteria = new FindCriteria();
        findCriteria.Duration = new TimeSpan(0, 0, 2);//TimeSpan.MaxValue;
        findCriteria.MaxResults = int.MaxValue;
        discoveryClient.FindAsync(findCriteria);

        Console.ReadKey();
    }

    private static void discoveryClient_FindCompleted(object sender, FindCompletedEventArgs e)
    {
        Console.WriteLine("Discovery complete");
    }

    static void discoveryClient_FindProgressChanged(object sender, FindProgressChangedEventArgs e)
    {

        foreach (var u in e.EndpointDiscoveryMetadata.ListenUris)
        {

            string uri = u.OriginalString;

            if (uri.Contains("http://192.168.1.162/onvif/device_service"))
            {

                Console.WriteLine(uri);

                EndpointAddress serviceAddress = new EndpointAddress(uri);

                HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();

                httpBinding.AuthenticationScheme = AuthenticationSchemes.Digest;

                var messegeElement = new TextMessageEncodingBindingElement();

                messegeElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);

                CustomBinding bind = new CustomBinding(messegeElement, httpBinding);

                DeviceClient client = new DeviceClient(bind, serviceAddress);

                // Add our custom behavior - this require the Microsoft WSE 3.0 SDK
                PasswordDigestBehavior behavior = new PasswordDigestBehavior("test", "test");

                client.Endpoint.Behaviors.Add(behavior);

                foreach (Service s in client.GetServices(false))
                    Console.WriteLine(s.ToString());

                client.Open();

                Console.WriteLine("WSDL = " + client.GetWsdlUrl());
                Console.WriteLine("DateTime = " + client.GetSystemDateAndTime());

                string a1, b1, c1, d1;
                Console.Write(client.GetDeviceInformation(out a1, out b1, out c1, out d1));

            }
        }
    }
}
Wireshark(用户名和密码都是测试)

POST/onvif/device\u服务HTTP/1.1
内容类型:应用程序/soap+xml;字符集=utf-8;行动=”http://www.onvif.org/ver10/device/wsdl/GetServices"
主持人:192.168.1.162
内容长度:1232
预期:100人继续
接受编码:gzip,deflate
连接:保持活力
UIDPO7UVMA6HRQNDH2L2ZDNZIAAAA2/ITWE91IUANFF3FUOBAYZ0MZ6QVNZPPBLYRNJBD1QGSACQAA
测试
WSKWE5XJP5APIIA9JICCOODKU=
6sYgS41VHsWKj7n8TNKFjA==
2013-08-09T14:52:45Z
假的
HTTP/1.1400错误请求
服务器:gSOAP/2.7
内容类型:应用程序/soap+xml;字符集=utf-8
内容长度:2751
连接:关闭
UIDPO7UVMA6HRQNDH2L2ZDNZIAAAA2/ITWE91IUANFF3FUOBAYZ0MZ6QVNZPPBLYRNJBD1QGSACQAA
SOAP-ENV:发送方
三:未授权
发件人未经授权
请求的操作需要授权,而发件人未经授权

我已在相机上启用onvif(通过创建名为“test”的管理员用户,并使用密码“test”。相机密码是默认的“root”和“pass”,因为它是Axis相机。

通过以下方式配置与相机的连接:

    ServicePointManager.Expect100Continue = false;
    var endPointAddress = new EndpointAddress("http://" + cameraAddress + "/onvif/device_service");
    var httpTransportBinding = new HttpTransportBindingElement { AuthenticationScheme = AuthenticationSchemes.Digest };
    var textMessageEncodingBinding = new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None) };
    var customBinding = new CustomBinding(textMessageEncodingBinding, httpTransportBinding);
    var passwordDigestBehavior = new PasswordDigestBehavior(adminName, adminPassword);
    var deviceClient = new DeviceClient(customBinding, endPointAddress);
    deviceClient.Endpoint.Behaviors.Add(passwordDigestBehavior);

我知道这几乎就是您所做的,但重要的是要使
服务点管理器。Expect100 Continue
为false。

检查摄像头是否启用了重放攻击保护功能。如果启用,请检查计算机时间与摄像头时间之间的时差。根据ONVIF的规格,允许的时差e必须为+-5秒。否则您将得到错误

如果这是您的情况,您有几个选择:

1-禁用回放攻击保护功能。不建议这样做,因为您需要在所有需要使用的摄像头中禁用此功能

2-您可以将相机的时间与计算机时间同步。同样,对于第一个选项的同一问题,不建议使用此选项

3-如果您可以为其他选项更改WSE 3.0。在WSE3.0中,一旦您创建了UsernameToken,您就不能更改用于创建加密的created属性。此问题在中进行了描述

    ServicePointManager.Expect100Continue = false;
    var endPointAddress = new EndpointAddress("http://" + cameraAddress + "/onvif/device_service");
    var httpTransportBinding = new HttpTransportBindingElement { AuthenticationScheme = AuthenticationSchemes.Digest };
    var textMessageEncodingBinding = new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None) };
    var customBinding = new CustomBinding(textMessageEncodingBinding, httpTransportBinding);
    var passwordDigestBehavior = new PasswordDigestBehavior(adminName, adminPassword);
    var deviceClient = new DeviceClient(customBinding, endPointAddress);
    deviceClient.Endpoint.Behaviors.Add(passwordDigestBehavior);