Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • How to resolve Http 400 Bad Request while authenticating with ONVIF camera

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 2.17k
    Comment on it

    The main point while authenticating with Onvif camera using Onvif wsdl is to create our custom behavior class and pass the camera credentials using that class. Here, below is the code for custom behavior class.

     

    Adding namespace:

    using System.ServiceModel.Description;
    using Microsoft.Web.Services2.Security.Tokens;
    using System;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.Xml;
    public class PasswordDigestBehavior : IEndpointBehavior
    {
    
    	public string Username { get; set; }
    	public string Password { get; set; }
    
    	public PasswordDigestBehavior(string username, string password)
    	{
    		this.Username = username;
    		this.Password = password;
    	}
    
    	#region IEndpointBehavior Members
    
    	public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    	{
    	   
    	}
    
    	public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    	{
    		clientRuntime.MessageInspectors.Add(new PasswordDigestMessageInspector(this.Username, this.Password));
    	}
    
    	public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    	{
    	   
    	}
    
    	public void Validate(ServiceEndpoint endpoint)
    	{
    		
    	}
    
    	#endregion
    }

     

    public class PasswordDigestMessageInspector : IClientMessageInspector
    {
    	public string Username { get; set; }
    	public string Password { get; set; }
    
    	public PasswordDigestMessageInspector(string username, string password)
    	{
    		this.Username = username;
    		this.Password = password;
    	}
    
    	public void AfterReceiveReply(ref Message reply, object correlationState)
    	{
    
    	}
    
    	public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    	{
    		UsernameToken token = new UsernameToken(this.Username, this.Password, PasswordOption.SendHashed);
    
    		// Serialize the token to XML
    		XmlDocument xmlDoc = new XmlDocument();
    		XmlElement securityToken = token.GetXml(xmlDoc);
    
    		// find nonce and add EncodingType attribute for BSP compliance
    		XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
    		nsMgr.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    		XmlNodeList nonces = securityToken.SelectNodes("//wsse:Nonce", nsMgr);
    		XmlAttribute encodingAttr = xmlDoc.CreateAttribute("EncodingType");
    		encodingAttr.Value = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
    		if (nonces.Count > 0)
    		{
    			nonces[0].Attributes.Append(encodingAttr);
    		}
    		MessageHeader securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityToken, false);
    		request.Headers.Add(securityHeader);
    
    		// complete
    		return Convert.DBNull;
    	}
    }

     

    After creating PasswordDigestBehavior class, simply add the given below code. Here below is the example of Media service in Onvif wsdl.

     

    ServicePointManager.Expect100Continue = false;
    // using this endpoint url  "http://ONVIF-IP-ADDRESS/onvif/services" , we can call deviceIO, devicemanagement and media services in Onvif wsdl
    EndpointAddress endPointAddress = new EndpointAddress("http://" + "ONVIF-IP-ADDRESS" + "/onvif/services");
    HttpTransportBindingElement httpTransportBinding = new HttpTransportBindingElement { AuthenticationScheme = AuthenticationSchemes.Digest };
    TextMessageEncodingBindingElement textMessageEncodingBinding = new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None) };
    CustomBinding customBinding = new CustomBinding(textMessageEncodingBinding, httpTransportBinding);
    //Pass camera username and password without any conversion
    PasswordDigestBehavior passwordDigestBehavior = new PasswordDigestBehavior("username", "password");  //Use our custom behaviour class that I created above
    MediaClient mediaClient = new MediaClient(customBinding, endPointAddress);
    mediaClient.Endpoint.Behaviors.Add(passwordDigestBehavior);        
    Profile[] profs = mediaClient.GetProfiles();
    Profile profile = mediaClient.GetProfile(profs[0].token);
    

     

    Hope this code will help you. Thanks.

     

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: