Saturday, July 6, 2013

CSharp C# Impersonation Simple Example

CSharp C# Impersonation Simple Example


TOC
Program.cs
ImpersonationHelper.cs


meta: user domain password act as impersonate

Program.cs:


using System;
using System.Security.Principal;


namespace Stuff4
{
   class Program
   {
       static void Main(string[] args)
       {
           Console.Clear();
           //----------------------------


           ImpersonationHelper impersonationHelper = new ImpersonationHelper();
           string DomainNameForVMS = MyDomain";
           string UserNameForVMS = "MyUserName";
           string UserPasswordForVMS = "MyPassword";
           if (!impersonationHelper.ImpersonateTestUser(DomainNameForVMS,
                                                        UserNameForVMS,
                                                        UserPasswordForVMS))
           
           {
               Console.WriteLine("Unable to set up impersonation.");
               Console.WriteLine("Press enter to finish program.");
               Console.ReadLine();
               return;
           }
           Console.WriteLine("Current user (should be the test user) = {0}", impersonationHelper.CurrenttWindowsIdentity());
           impersonationHelper.SwitchToOriginalUser();
           Console.WriteLine("Current user (should be the non-Test user) = {0}", impersonationHelper.CurrenttWindowsIdentity());
           impersonationHelper.SwitchToTestlUser();
           Console.WriteLine("Current user (should be the Test user) = {0}", impersonationHelper.CurrenttWindowsIdentity());
           impersonationHelper.JustRevertToOriginalUser();
           Console.WriteLine("Current user [after JustRevertToOriginalUser()]  (should be the Non-Test user) = {0}", WindowsIdentity.GetCurrent().Name);


           //----------------------------r
           Console.WriteLine();
           Console.WriteLine("done");
           Console.ReadLine();
       }
   }
}



ImpersonationHelper.cs:


using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;  //For DLLImport call below
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;



namespace Stuff4
{
      public class ImpersonationHelper
   {
       public WindowsIdentity newId = null;
       public WindowsIdentity originalId = null;
       private SafeTokenHandle safeTokenHandle = null;
       private WindowsImpersonationContext impersonatedUser;
       [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
       public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
           int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
       [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
       public extern static bool CloseHandle(IntPtr handle);
       [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
       public void SwitchToOriginalUser()
       {
           if (originalId == null)
           {
               throw new Exception("Original user must be set up first with call to ImpersonateTestUser!");
           }
           else
           {
               ImpersonateUserNow(originalId);
           }
       }
       [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
       public bool SwitchToTestlUser()
       {
           if (newId == null)
           {
               throw new Exception("Test user must be set up first with call to ImpersonateTestUser!");
           }
           else
           {
               ImpersonateUserNow(newId);
               return true;
           }
       }
       [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
       public bool ImpersonateTestUser(string userDomainNameNow, string userNameNow, string userPasswordNow)
       {
           try
           {
               const int LOGON32_PROVIDER_DEFAULT = 0;
               //This parameter causes LogonUser to create a primary token.
               const int LOGON32_LOGON_INTERACTIVE = 2;
               // Call LogonUser to obtain a handle to an access token.
               bool returnValue = LogonUser(userNameNow, userDomainNameNow, userPasswordNow,
                   LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                   out safeTokenHandle);
               Console.WriteLine("LogonUser called: {0}\\{1}", userDomainNameNow, userNameNow);
               if (false == returnValue)
               {
                   int ret = Marshal.GetLastWin32Error();
                   Console.WriteLine("LogonUser failed with error code : {0}", ret);
                   throw new System.ComponentModel.Win32Exception(ret);
               }
               originalId = WindowsIdentity.GetCurrent();
               newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
               WindowsImpersonationContext impersonatedUser = newId.Impersonate();
           }
           catch (Exception ex)
           {
               Console.WriteLine("Exception occurred. " + ex.Message);
               return false;
           }
           return true;
       }
       public bool ImpersonateUserNow(WindowsIdentity userNow)
       {
           impersonatedUser = userNow.Impersonate();
           return true;
       }
       public string CurrenttWindowsIdentity()
       {
           return WindowsIdentity.GetCurrent().Name;
       }
       public void JustRevertToOriginalUser()
       {
           impersonatedUser.Undo();
       }
   }
   public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
   {
       private SafeTokenHandle()
           : base(true)
       {
       }
       [DllImport("kernel32.dll")]
       [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
       [SuppressUnmanagedCodeSecurity]
       [return: MarshalAs(UnmanagedType.Bool)]
       private static extern bool CloseHandle(IntPtr handle);
       protected override bool ReleaseHandle()
       {
           return CloseHandle(handle);
       }
   }
}


No comments:

Post a Comment