Wednesday, July 23, 2014

Impersonating the Service or application with given windows user id and password

You might have faced a situation where your service has to be Impersonated for given user id and password, instead of giving access to all the users who login to the application.
So With impersonation you could just grant one account rights and make your application use those user id and password to access those resources whn every any user tries to access those resources.

Add this below class under your project.

       
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;


namespace Utility
{
    /// 
    /// Summary description for LogonAPI
    /// 
    public class LogonAPI : IDisposable
    {
        public const int LOGON32_LOGON_INTERACTIVE = 9;
        public const int LOGON32_PROVIDER_DEFAULT = 3;
        [DllImport("advapi32.dll")]
        public static extern int LogonUserA(String lpszUserName,
            String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        public LogonAPI()
        {
            throw new Exception("Improper usage of LogonAPI" + Environment.NewLine +
                                "use this Constructor instead:" + Environment.NewLine +
                                "LogonAPI(userName, domain, password)");
        }

        public LogonAPI(String userName, String domain, String password)
        {
            impersonateValidUser(userName, domain, password);
        }

        private WindowsImpersonationContext Impersonatecontext;
        public void impersonateValidUser(String userName, String domain, String password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;
            Impersonatecontext=null;

            if (RevertToSelf())
            {
                if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        Impersonatecontext = tempWindowsIdentity.Impersonate();
                        if (Impersonatecontext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
        }
        //public void undoImpersonation(WindowsImpersonationContext impersonationContext)
        //{
        //    impersonationContext.Undo();
        //}

        #region IDisposable Members

        public void Dispose()
        {
            try
            {
                Impersonatecontext.Undo();
                Impersonatecontext.Dispose();
            }
            catch(Exception ex)
            {
                LogWriter.Current.WriteException(ex);
            }
            
        }

        #endregion
    }

}

Now comes how to use this impersonation.

Lets say u have a class and have a method, this method is trying to access some cross network resources like trying to access a file or create a file or etc. so this function needs to be impersonated so you application dose not need any special person when every any user performs an action.


       
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    public class createfileovernetwork
    {
        public StreamWriter mSW;


        public createfileovernetwork()
        {

        }

        public void Createfile()
        {
            using (LogonAPI objLogonAPI = new LogonAPI("Username", "DomainName", "Password"))
            {
                // do the stuf here
            }
        }
    }
}

Tuesday, July 8, 2014

Validating XML against XSD using C#

On a day to day we might face a scenario where we end up having an XML validated against XSD.
I too faced the same scenario where some of our Tier 2 and BA's wants to test some of their files form customers are valid or not. we have a system which validates and rejects the files which don't match with a proper XSD, but Tier 2 wants to do it before hand some times instead of flowing it through the system.
Below is the method which we can use with in our Windows or web application where we can have user input XML and XSD and have them validated against and show all the errors if they don't match.
       
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;

namespace XmltoXpathnamespace
{
    public class XmltoXpath
    {
        private List _listOfErrorMessages = null;
        public string _errormessagesconcatinated = string.Empty;

        public bool IsXMLValidAgainstXSD(string xml_To_Validate, string xsd_To_Validate_Against)
        {
            bool validXML = true;
            try
            {
                _listOfErrorMessages = new List();
                XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
                xmlSchemaSet.Add(string.Empty, XmlReader.Create(new StringReader(xsd_To_Validate_Against)));
                XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
                xmlReaderSettings.IgnoreComments = true;
                xmlReaderSettings.IgnoreWhitespace = true;
                xmlReaderSettings.ValidationType = ValidationType.Schema;
                xmlReaderSettings.Schemas.Add(xmlSchemaSet);
                xmlReaderSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
                ValidationEventHandler validationEventHandler = (sender, args) =>
                {
                    validXML = false;
                    ErrMsg errMsg = new ErrMsg();
                    errMsg.parentName = ((XmlReader)sender).Name.ToString();
                    errMsg.entityIDCode = ((XmlReader)sender).GetAttribute("EntityIDCode") == null ? string.Empty : ((XmlReader)sender).GetAttribute("EntityIDCode").ToString();
                    PropertyInfo propInfo = args.Exception.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "Args");
                    errMsg.attributeName = propInfo.GetValue(args.Exception, null) == null ? string.Empty : ((string[])propInfo.GetValue(args.Exception, null))[0];
                    errMsg.errorMessage = args.Exception.Message.Replace("'", string.Empty);
                    errMsg.lineNumber = args.Exception.LineNumber.ToString();
                    _listOfErrorMessages.Add(errMsg);
                    _errormessagesconcatinated += string.Format("ErrorMessage: {0} Line number: {1} \r\n", errMsg.errorMessage, errMsg.lineNumber);
                };

                xmlReaderSettings.ValidationEventHandler += validationEventHandler;
                using (XmlReader xmlReader = XmlReader.Create(new StringReader(xml_To_Validate), xmlReaderSettings))
                {
                    while (xmlReader.Read()) ;
                }
                xmlReaderSettings.ValidationEventHandler -= validationEventHandler;
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("ERROR: Exception caught in IsXMLValidAgainstSingleXSD: {0}", ex.Message));
            }
            return validXML;
        }

        private class ErrMsg
        {
            public string parentName { get; set; }
            public string attributeName { get; set; }
            public string errorMessage { get; set; }
            public string entityIDCode { get; set; }
            public string lineNumber { get; set; }
        }
    }  
}

Generating Xpaths out of Xml file

We came across a situation where one of our BA wants to have X paths listed in his specification for a given XML and the XML which he is looking at is huge. So he asked our development team to create tool where he can give the XML and can get all the X paths list out where he can save.
Below is the details of the function where given an XML document we can generate X paths out of it.


       

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace ClassLibrary1
{
    public class XmltoXpath
    {
        public string Xpathlist = string.Empty;

        public void getXpathsfromxml(string xmlcontent)
        {
            try
            {

                 XmlDocument dom = new XmlDocument();
                try
                {
                    dom.LoadXml(xmlcontent);
                }
                catch(Exception e)
                {
                    throw new Exception("Error: file is not a valid xml. Original error: " + e.Message);
                }

                XmlNode rootnode = (XmlNode)dom.DocumentElement;
                EnumerateChildren(ref rootnode, "/" + rootnode.Name);

            }
            catch(Exception ex)
            {
                throw new Exception("Error: generating Xpaths from xml. Original error: " + ex.Message);
            }
        }

        private void EnumerateChildren(ref XmlNode elem, string Xpath)
        {
            EnumerateAttributes(ref elem, Xpath);
            XmlNode children;
            if(elem.HasChildNodes)
            {

                foreach (XmlNode child in elem.ChildNodes)
                {
                    children = child;
                    if (child.Name=="#text")
                    {
                        Xpathlist = Xpathlist + string.Format("{0}=\"{1}\"\r\n",Xpath, child.Value);
                    }
                    else
                    {
                        EnumerateChildren(ref children, Xpath + "/" + child.Name);
                    }
                }
            }

        }

        private void EnumerateAttributes(ref XmlNode node,string Xpath)
        {
            try
            {
                XmlAttributeCollection attributes = node.Attributes;
                foreach(XmlAttribute att in attributes)
                {
                    Xpathlist = Xpathlist + string.Format("{0}/@{1}\r\n",Xpath, att.OuterXml);
                }
            }
            catch(Exception ex)
            {

            }

        }

   }
}