Unable to connect to OnVif enabled camera using C# - c#

I am working with IPCams for the first time and I am trying to connect to an OnVif camera. I have looked on various forums and stack overflow and I have come up with the following code.I know the code doesn't do anything useful but it is just a proof of concept for now. It finds all 4 cameras on my network and then I am manually connecting to one of them to pull back some information such as GetServices.
I get a 400 bad response error at this stage. I have looked at the traffic back and forth with WireShark and it appears that everything is working ok regarding the password being generated in so far as I can tell (security and encryption is not my area at all!).
Can anyone help or advise?
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 (username and passwor are both test)
POST /onvif/device_service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/GetServices"
Host: 192.168.1.162
Content-Length: 1232
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo7uVma6HRQNDh2l6T2ZDNzIAAAAA2/ITWE91IUaNFF3UObayz0mz6QvnZppBlYrNJBd1QGsACQAA</VsDebuggerCausalityData>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="SecurityToken-56f9081e-e9b4-4660-9158-7419af1efde0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>test</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">WSKWE5XjP5aPiIiA9JicCOYoDkU=</wsse:Password>
<wsse:Nonce>6sYgS41VHsWKj7n8TNKFjA==</wsse:Nonce>
<wsu:Created>2013-08-09T14:52:45Z</wsu:Created>
</wsse:UsernameToken>
</Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetServices xmlns="http://www.onvif.org/ver10/device/wsdl">
<IncludeCapability>false</IncludeCapability>
</GetServices>
</s:Body>
</s:Envelope>HTTP/1.1 400 Bad Request
Server: gSOAP/2.7
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 2751
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" xmlns:aa="http://www.axis.com/vapix/ws/action1" xmlns:aev="http://www.axis.com/vapix/ws/event1" xmlns:tan1="http://www.onvif.org/ver20/analytics/wsdl/RuleEngineBinding" xmlns:tan2="http://www.onvif.org/ver20/analytics/wsdl/AnalyticsEngineBinding" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tev1="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" xmlns:tev2="http://www.onvif.org/ver10/events/wsdl/EventBinding" xmlns:tev3="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:tev4="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tnsaxis="http://www.axis.com/2009/event/topics">
<SOAP-ENV:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo7uVma6HRQNDh2l6T2ZDNzIAAAAA2/ITWE91IUaNFF3UObayz0mz6QvnZppBlYrNJBd1QGsACQAA</VsDebuggerCausalityData>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<SOAP-ENV:Fault SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<SOAP-ENV:Code>
<SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value>
<SOAP-ENV:Subcode>
<SOAP-ENV:Value>ter:NotAuthorized</SOAP-ENV:Value>
</SOAP-ENV:Subcode>
</SOAP-ENV:Code>
<SOAP-ENV:Reason>
<SOAP-ENV:Text xml:lang="en">Sender not authorized</SOAP-ENV:Text>
</SOAP-ENV:Reason>
<SOAP-ENV:Detail>
<SOAP-ENV:Text>The action requested requires authorization and the sender is not authorized</SOAP-ENV:Text>
</SOAP-ENV:Detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I have onvif enabled on the camera (by creating an administrator user called "test" with a password "test". The camera password is the default "root" and "pass" as it is an Axis camera.

Configure the connection to the camera this way:
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);
I know it's almost what you have done but it is important to make ServicePointManager.Expect100Continue false.

Check if the camera have the replay attack protection enabled. If so check the time difference between your computer's time and the camera's. According to the ONVIF's specs the allowed time difference must be +- 5 seconds. Otherwise you get your error.
If this is your case you have several options:
1- Disable the replay attack protection feature. This is not recommended because you would need to disable this feature in all the cameras you need to work with.
2- You can sync the camera's time with your computer time. Again not recommended for the same issue of the first option.
3- If you can change the WSE 3.0 for other option. In WSE3.0 once you have created the UsernameToken you can't change the Created property, which is used to create the encryption. This problem is described in here

Related

Overwrite WS-Adressing-Header (to and Action)

i have to access an SOAP-service with WS-Adressing. I simply imported the WSDL i got and i try to connect. But the Service is not happy with the generated WS-Adressing Headers.
My code looks like this:
var binding = new WSHttpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var entpointAddr = new EndpointAddress("https://endpoint123/services");
using (var client = new DocumentManagementServicePortTypeClient(binding, entpointAddr))
{
client.ClientCredentials?.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "123123123");
try
{
var result = client.TestFunction();
Console.WriteLine(result);
}
catch (Exception exc)
{
Console.WriteLine($"Error: {exc.Message}");
}
}
This generate a Request like this:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1"/>
<a:MessageID>urn:uuid:8123d133-c107-44cf-97be-762014fa1b83</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">https://endpoint123/services</a:To>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<TestFunction xmlns = "http://xmldefs...../" />
</ s:Body>
</s:Envelope>
The Server has two problems with this request:
a:To is pointed to the Endpoint
a:Action is empty
The a:To is pointed to the endpoint i set in my code-snippet. But the server expected the Endpoint defined in the WSDL (a WS:\\ uri). How could i tell WCF to use the WS:\\-Link? Or could i overwrite it manually?
I could solve the problem with the a:Action by manually adding the path in the Reference.cs, for every function i like to use, but why it is not self generated?

Exception when subscribing to exchange streaming notifications

I'm currently working on a project that has me integrating with Exchange. One of the requirements is to monitor mailboxes for new incoming messages and I thought that leveraging a streaming notifications would be a good idea.
I wrote a sample application to get familiar with how to leverage streaming notifications, however I am encountering the following error: The expected XML node type was Element, but the actual type is Text.
The following is the source of the sample application that I wrote:
using Microsoft.Exchange.WebServices.Data;
using System;
using System.Net;
namespace ExampleProgram
{
class Program
{
public static StreamingSubscriptionConnection streamingConnection;
public static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
public static void NewMailSubscriptionDisconnect(object sender, SubscriptionErrorEventArgs args)
{
Exception e = args.Exception;
Console.Write("Disconnect: ");
Console.WriteLine(e.Message);
if (streamingConnection != null && !streamingConnection.IsOpen)
{
streamingConnection.Open();
}
}
public static void NewMailSubscriptionError(object sender, SubscriptionErrorEventArgs args)
{
Exception e = args.Exception;
Console.Write("Disconnect: ");
Console.WriteLine(e.Message);
}
public static void NewMailSubscriptionNotification(object sender, NotificationEventArgs args)
{
Console.WriteLine("New message has arrived");
}
static void Main(string[] args)
{
var exchangeService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exchangeService.Credentials = new NetworkCredential("username", "password", "domain");
exchangeService.TraceEnabled = true;
exchangeService.TraceFlags = TraceFlags.All;
exchangeService.TraceEnablePrettyPrinting = true;
exchangeService.AutodiscoverUrl("username#example.com", RedirectionUrlValidationCallback);
var newMailSubscription = exchangeService.SubscribeToStreamingNotificationsOnAllFolders(EventType.NewMail);
streamingConnection = new StreamingSubscriptionConnection(exchangeService, 30);
streamingConnection.AddSubscription(newMailSubscription);
streamingConnection.OnNotificationEvent += new StreamingSubscriptionConnection.NotificationEventDelegate(NewMailSubscriptionNotification);
streamingConnection.OnSubscriptionError += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(NewMailSubscriptionError);
streamingConnection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(NewMailSubscriptionDisconnect);
streamingConnection.Open();
do { } while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
}
}
As you can see from the above source, I have tracing turned on. The following is what is yielded from those traces:
EwsResponseHttpHeader
<Trace Tag="EwsResponseHttpHeaders" Tid="17" Time="2015-10-20 17:42:31Z">
HTTP/1.1 200 OK
Transfer-Encoding: chunked
request-id: <redacted>
X-CalculatedBETarget: EXAMPLE-EXCHANGE-01.example.com
X-NoBuffering: 1
X-DiagInfo: EXAMPLE-EXCHANGE-01
X-BEServer: EXAMPLE-EXCHANGE-01
Cache-Control: private
Set-Cookie: exchangecookie=<redacted>; path=/,X-BackEndCookie=<redacted>; expires=Thu, 19-Nov-2015 17:42:30 GMT; path=/ews; secure; HttpOnly
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
X-FEServer: EXAMPLE-EXCHANGE-02
Date: Tue, 20 Oct 2015 17:42:30 GMT
</Trace>
EwsResponse
<Trace Tag="EwsResponse"
Tid="15"
Time="2015-10-20 16:52:07Z"
Version="0.0.0.0">
417 <!-- What is this? -->
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="1130"
MinorBuildNumber="6"
Version="V2_23"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:GetStreamingEventsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ConnectionStatus>OK</m:ConnectionStatus>
</m:GetStreamingEventsResponseMessage>
</m:ResponseMessages>
</m:GetStreamingEventsResponse>
</soap11:Body>
</Envelope>
2 <!-- Not sure what this is either... -->
</Trace>
Exception Detail
Microsoft.Exchange.WebServices.Data.ServiceXmlDeserializationException occurred
HResult=-2146233088
Message=The expected XML node type was Element, but the actual type is Text.
Source=Microsoft.Exchange.WebServices
StackTrace:
at Microsoft.Exchange.WebServices.Data.EwsXmlReader.Read(XmlNodeType nodeType) in C:\Projects\ews-managed-api\Core\EwsXmlReader.cs:line 187
InnerException:
The source of EwsXmlReader.cs can be found at: https://github.com/OfficeDev/ews-managed-api/blob/master/Core/EwsXmlReader.cs
It looks like "something" is prepending 417 and appending 2 to the response from the Exchange server. It's quite obvious to me why the exception is being thrown, there is text data where there shouldn't be. What's not obvious to me, is why that text data is there.
Any ideas?
Transfer-Encoding: chunked
That's the key to this puzzle, you are seeing the "chunks". 417 is a value in hexadecimal for the length of the <Envelope> chunk when you remove the pretty-print formatting. 2 is the final chunk, just whitespace. Chunked transfer formatting is explained here.
I reformatted the XML to remove the white space, You can count off exactly 0x417 = 1047 characters:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><soap11:Header xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"><ServerVersionInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="0" MajorBuildNumber="1130" MinorBuildNumber="6" Version="V2_23" xmlns="http://schemas.microsoft.com/exchange/services/2006/types"/></soap11:Header><soap11:Body xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"><m:GetStreamingEventsResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"><m:ResponseMessages><m:GetStreamingEventsResponseMessage ResponseClass="Success"><m:ResponseCode>NoError</m:ResponseCode><m:ConnectionStatus>OK</m:ConnectionStatus></m:GetStreamingEventsResponseMessage></m:ResponseMessages></m:GetStreamingEventsResponse></soap11:Body></Envelope>
Obviously the http transfer is supposed to remove them, your question gives no decent lead why this did not happen. But hopefully a pretty good lead to find the underlying cause. Fun puzzle btw :)

WCF client security header error "An invalid security token was provided"

According to our provider we need to send this kind of Header:
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-12" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>string</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">string</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
But when checking out with Fiddler I sent this header:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo/HuqG5V/ExLj3CNfRenvjEAAAAA7YcLXCnGukqViuu2jfqDDp47VC4vVV1Omqf/X2lHIcsACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-5d0431d0-d951-4a22-91c1-a33d76ce41b3-1">
<o:Username>username</o:Username>
<o:Password>password</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
I'm using a custom Binding as follows (I used it on another webservice with the same authetication method and works ok)
private static Binding CreateMultiFactorAuthenticationBinding()
{
HttpsTransportBindingElement httpTransport = new HttpsTransportBindingElement();
httpTransport.MaxReceivedMessageSize = int.MaxValue;
//AddressHeader addressHeader = AddressHeader.CreateAddressHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", security, xmlObjectSerializer);
CustomBinding binding = new CustomBinding();
binding.Name = "myCustomBinding";
TransportSecurityBindingElement messageSecurity = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement();
messageSecurity.IncludeTimestamp = false;
messageSecurity.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12;
messageSecurity.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
messageSecurity.SetKeyDerivation(false);
TextMessageEncodingBindingElement Quota = new TextMessageEncodingBindingElement(MessageVersion.Soap11, System.Text.Encoding.UTF8);
Quota.ReaderQuotas.MaxDepth = 32;
Quota.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
Quota.ReaderQuotas.MaxArrayLength = 16384;
Quota.ReaderQuotas.MaxBytesPerRead = 4096;
Quota.ReaderQuotas.MaxNameTableCharCount = 16384;
binding.Elements.Add(Quota);
binding.Elements.Add(messageSecurity);
binding.Elements.Add(httpTransport);
return binding;
}
private WaybillManagementPOD GetClient()
{
CustomBinding customBinding = (CustomBinding)CreateMultiFactorAuthenticationBinding();
EndpointAddress endpointAddress = new EndpointAddress(this.EndPointAddr);
WaybillManagementPOD proxy = ChannelFactory<WaybillManagementPOD>.CreateChannel(customBinding, endpointAddress);
ServicePointManager.ServerCertificateValidationCallback = (obj, certificate, chain, errors) => true;
ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
ChannelFactory _bankChannel = new ChannelFactory<WaybillManagementPOD>(customBinding, this.EndPointAddr);
ChannelFactory<WaybillManagementPOD> channelFactory = null;
WaybillManagementPOD client = null;
channelFactory = new ChannelFactory<WaybillManagementPOD>(customBinding, endpointAddress);
channelFactory.Credentials.UserName.UserName = this.WsUser;
channelFactory.Credentials.UserName.Password = this.WsPass;
client = channelFactory.CreateChannel();
return client;
}
public registrarCartaDePorteResponse registrarCP(ParametrosRegistro reg)
{
WaybillManagementPOD cliente = GetClient();
try
{
registrarCartaDePorte req = new registrarCartaDePorte(reg);
registrarCartaDePorteResponse resp = cliente.registrarCartaDePorte(req);
return resp;
}
catch (Exception e)
{
throw e;
}
}
PS: I know it's not of good practice to bypass SSL certificate, but right now is for testing only.
Neither my provider nor I cannot figure out where is the error coming from, or where the error lies, if it's in the type of binding or something else.
I finally used as suggested here Correct way communicate WSSE Usernametoken for SOAP webservice
<endpoint ...>
<headers>
<wsse:UsernameToken xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' >
<wsse:Username>Bob</wsse:Username>
<wsse:Password Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'>
1234
</wsse:Password>
</wsse:UsernameToken>
</headers>
</endpoint>
</client>
Also now I call the webservice directly from the class created by the WCF reference, instead of using the custom class above.
Plus copying the information from the service solution to the UI solution, see here: WCF Error - Could not find default endpoint element that references contract 'UserService.UserService'
Now everything seems working fine.

How to get device information using Onvif library c#?

I am making a c# windows application which collects the devices connected to my network using an open source library Onvif.
i am doing in this way.
ServicePointManager.Expect100Continue = false;
var endPointAddress = new EndpointAddress("http://ip_address:port/onvif/device_service");
var httpBinding = new HttpTransportBindingElement();
var bind = new CustomBinding(httpBinding);
var temp = new DeviceClient(bind, endPointAddress);
var request = new GetDeviceInformationRequest();
var response = temp.GetDeviceInformation(request); ////// Error Here described bellow
string firm = response.FirmwareVersion;
string manu = response.Manufacturer;
string serial = response.SerialNumber;
string model = response.Model;
Error Message :: There was no endpoint listening at http:// something:port/onvif/device_service that could accept the message.this is often caused by an incorrect address or SOAP action
can any one help me?
I think i am not making proper connection with the server, is it so?
if so then how to resolve it?
Maybe the WS-DISCOVERY gives you extra information. I would try not to use any port after the IP of the camera.
When the test sends an UDP to the multicast address 239.255.255.250, port 3702 (WS-Discovery), this is the camera's answer:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:dn="http://www.onvif.org/ver10/network/wsdl">
<SOAP-ENV:Header>
<wsa:MessageID>uuid:cb3dea50-aa60-11e1-88b9-00408cb972aa</wsa:MessageID>
<wsa:RelatesTo>uuid:5bca11ff-61b8-4d07-8a26-90274ad51db8</wsa:RelatesTo>
<wsa:To SOAP-ENV:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
<wsa:Action SOAP-ENV:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</wsa:Action>
<d:AppSequence SOAP-ENV:mustUnderstand="true" MessageNumber="1" InstanceId="1338367479"></d:AppSequence>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<d:ProbeMatches>
<d:ProbeMatch>
<wsa:EndpointReference>
<wsa:Address>urn:uuid:65a142fc-a41e-11e1-9cc8-00408cb972aa</wsa:Address>
</wsa:EndpointReference>
<d:Types>dn:NetworkVideoTransmitter</d:Types>
<d:Scopes>
onvif://www.onvif.org/type/video_encoder
onvif://www.onvif.org/type/ptz
onvif://www.onvif.org/hardware/P5534-E
onvif://www.onvif.org/name/AXIS%20P5534-E
onvif://www.onvif.org/location/
</d:Scopes>
<d:XAddrs>
h##p://zeroconfIP/onvif/device_service
h##p://unicastIP/onvif/device_service
</d:XAddrs>
<d:MetadataVersion>1</d:MetadataVersion>
</d:ProbeMatch>
</d:ProbeMatches>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Try to discover the response and see if any XAddrs is not the default you expect.
Foscam FI9805E soap response on ONVIF GetCapabilities
-
-
-<tds:GetCapabilitiesResponse>
-<tds:Capabilities xsi:type="tt:Capabilities">
-<tt:Analytics xsi:type="tt:AnalyticsCapabilities">
<tt:XAddr>http://192.168.1.210:8888/onvif/device_service</tt:XAddr>
<tt:RuleSupport>true</tt:RuleSupport>
<tt:AnalyticsModuleSupport>true</tt:AnalyticsModuleSupport>
</tt:Analytics>
-<tt:Device xsi:type="tt:DeviceCapabilities">
<tt:XAddr>http://192.168.1.210:8888/onvif/device_service</tt:XAddr>
-<tt:Network xsi:type="tt:NetworkCapabilities">
<tt:IPFilter>false</tt:IPFilter>
<tt:DynDNS>true</tt:DynDNS>
</tt:Network>
-<tt:System xsi:type="tt:SystemCapabilities">
<tt:DiscoveryResolve>true</tt:DiscoveryResolve>
<tt:DiscoveryBye>true</tt:DiscoveryBye>
<tt:RemoteDiscovery>false</tt:RemoteDiscovery>
<tt:SystemBackup>true</tt:SystemBackup>
<tt:SystemLogging>true</tt:SystemLogging>
<tt:FirmwareUpgrade>true</tt:FirmwareUpgrade>
-<tt:SupportedVersions xsi:type="tt:OnvifVersion">
<tt:Major>2</tt:Major>
<tt:Minor>21</tt:Minor>
</tt:SupportedVersions>
</tt:System>
-<tt:Security xsi:type="tt:SecurityCapabilities">
<tt:TLS1.1>false</tt:TLS1.1>
<tt:TLS1.2>false</tt:TLS1.2>
<tt:OnboardKeyGeneration>false</tt:OnboardKeyGeneration>
<tt:AccessPolicyConfig>true</tt:AccessPolicyConfig>
<tt:X.509Token>false</tt:X.509Token>
<tt:SAMLToken>false</tt:SAMLToken>
<tt:KerberosToken>false</tt:KerberosToken>
<tt:RELToken>false</tt:RELToken>
</tt:Security>
</tt:Device>
-<tt:Events xsi:type="tt:EventCapabilities">
<tt:XAddr>http://192.168.1.210:8888/onvif/device_service</tt:XAddr>
<tt:WSSubscriptionPolicySupport>false</tt:WSSubscriptionPolicySupport>
<tt:WSPullPointSupport>true</tt:WSPullPointSupport>
<tt:WSPausableSubscriptionManagerInterfaceSupport>false</tt:WSPausableSubscriptionManagerInterfaceSupport>
</tt:Events>
-<tt:Imaging xsi:type="tt:ImagingCapabilities">
<tt:XAddr>http://192.168.1.210:8888/onvif/device_service</tt:XAddr>
</tt:Imaging>
-<tt:Media xsi:type="tt:MediaCapabilities">
<tt:XAddr>http://192.168.1.210:8888/onvif/device_service</tt:XAddr>
-<tt:StreamingCapabilities xsi:type="tt:RealTimeStreamingCapabilities">
<tt:RTPMulticast>false</tt:RTPMulticast>
<tt:RTP_TCP>true</tt:RTP_TCP>
<tt:RTP_RTSP_TCP>true</tt:RTP_RTSP_TCP>
</tt:StreamingCapabilities>
</tt:Media>
-<tt:PTZ xsi:type="tt:PTZCapabilities">
<tt:XAddr>http://192.168.1.210:8888/onvif/device_service</tt:XAddr>
</tt:PTZ>
-<tt:Extension xsi:type="tt:CapabilitiesExtension">
-<tt:DeviceIO xsi:type="tt:DeviceIOCapabilities">
<tt:XAddr/>
<tt:VideoSources>1</tt:VideoSources>
<tt:VideoOutputs>0</tt:VideoOutputs>
<tt:AudioSources>1</tt:AudioSources>
<tt:AudioOutputs>0</tt:AudioOutputs>
<tt:RelayOutputs>0</tt:RelayOutputs>
</tt:DeviceIO>
</tt:Extension>
</tds:Capabilities>
</tds:GetCapabilitiesResponse>

WCF set custom header - reading not working

I need to put custom headers into WCF. My Code is as follows:
ServiceReference1.Service2Client ws = new Service2Client();
using (OperationContextScope scope = new OperationContextScope((IContextChannel)ws.InnerChannel))
{
MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;
messageHeadersElement.Add(MessageHeader.CreateHeader("Authorization", String.Empty, "string"));
messageHeadersElement.Add(MessageHeader.CreateHeader("username", String.Empty, "user"));
var res = ws.GetUser("123");
}
But when I try to read it in the service, nothing is availabe in the following
public class OAuthAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
int index = OperationContext.Current.IncomingMessageHeaders.FindHeader("username", String.Empty);
string auth = operationContext.IncomingMessageHeaders.GetHeader<string>("username", String.Empty);
var hereIseeIt = operationContext.RequestContext.RequestMessage;
index is -1: not found
auth: is also displaying an exception that the header is not available
hereIseeIt: .ToString() shows a xml where I can see that user is existent, but I see no way to access that information in any of the objects
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<username xmlns="http://Microsoft.WCF.Documentation">user</username>
</s:Header>
<s:Body>
<GetUser xmlns="http://tempuri.org/">
<UserId>123</UserId>
</GetUser>
</s:Body>
</s:Envelope>
But I cannot access them since I find no way to access the s:Header ...
try using:
XPathNavigator XPN = operationContext.RequestContext.RequestMessage.CreateBufferedCopy ().CreateNavigator ();
NOT elegant but it gives you the whole Message accessible through a XPathNavigator which should make it easy to get to any value inside the Message you want..
some links:
http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.requestcontext.aspx
http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx
http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.aspx
Here's an easy way to get the inner XML of the username header for your scenario. Even if you already solved your issue a long time ago, I thought it might help somebody else who faces the same issue.
var username = String.Empty;
// using the namespace from you XML sample
var usernameHeaderPosition = OperationContext.Current
.IncomingMessageHeaders
.FindHeader("username", "http://Microsoft.WCF.Documentation");
if (usernameHeaderPosition > -1)
{
username = OperationContext.Current
.IncomingMessageHeaders
.GetReaderAtHeader(usernameHeaderPosition).ReadInnerXml();
}

Categories