How can I temporarily impersonate a user to open a file?

后端 未结 2 1361
梦谈多话
梦谈多话 2021-01-03 16:59

I would like to temporarily impersonate a domain user account to read in a file on a network drive from an ASP.NET site.

I would rather not set up impersonation for

相关标签:
2条回答
  • 2021-01-03 17:36

    I ended up using code from Michiel van Otegem: WindowsImpersonationContext made easy and added an implementation of IDisposable. I found this in another question about impersonation in ASP.NET.

    Usage:

    using (WindowsImpersonationContextFacade impersonationContext
         = new WindowsImpersonationContextFacade(
                        Settings.Default.ImpersonationDomain, 
                        Settings.Default.ImpersonationUser,
                        Settings.Default.ImpersonationPass))
                    {
                        transactions  = TransactionLoader.Load(filePath);
                    }
    

    Code:

    using System;
    using System.Runtime.InteropServices;
    using System.Security.Principal;
    using System.Security.Permissions;
    using System.ComponentModel;
    
    namespace MyNamespace
    {
        public class WindowsImpersonationContextFacade : IDisposable
        {
            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern bool LogonUser(String lpszUsername, String lpszDomain,
                                                String lpszPassword, int dwLogonType, int dwLogonProvider,
                                                ref IntPtr phToken);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern bool CloseHandle(IntPtr handle);
    
            private const int LOGON32_PROVIDER_DEFAULT = 0;
            private const int LOGON32_LOGON_INTERACTIVE = 2;
    
            private string m_Domain;
            private string m_Password;
            private string m_Username;
            private IntPtr m_Token;
    
            private WindowsImpersonationContext m_Context = null;
    
            protected bool IsInContext
            {
                get { return m_Context != null; }
            }
    
            public WindowsImpersonationContextFacade(string domain, string username, string password)
            {
                m_Domain = domain;
                m_Username = username;
                m_Password = password;
                Enter();
            }
    
            [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
            private void Enter()
            {
                if (this.IsInContext) return;
                m_Token = IntPtr.Zero;
                bool logonSuccessfull = LogonUser(
                    m_Username,
                    m_Domain,
                    m_Password,
                    LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT,
                    ref m_Token);
                if (logonSuccessfull == false)
                {
                    int error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error);
                }
                WindowsIdentity identity = new WindowsIdentity(m_Token);
                m_Context = identity.Impersonate();
            }
    
            [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
            private void Leave()
            {
                if (this.IsInContext == false) return;
                m_Context.Undo();
    
                if (m_Token != IntPtr.Zero) CloseHandle(m_Token);
                m_Context = null;
            }
    
            public void Dispose()
            {
                Leave();
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-03 17:49

    Actually, the process is quite easy, you can use code like this;

    using System.Security.Principal;
    ...
    // Obtain the authenticated user's Identity
    WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
    WindowsImpersonationContext ctx = null;
    try
    {
      // Start impersonating
      ctx = winId.Impersonate();
      // Now impersonating
      // Access resources using the identity of the authenticated user
    }
    // Prevent exceptions from propagating
    catch
    {
    }
    finally
    {
      // Revert impersonation
      if (ctx != null)
        ctx.Undo();
    }
    // Back to running under the default ASP.NET process identity
    

    Your code goes in the "Now impersonating" section. the KEY is the finally block, this is VERY important. You can view this MSDN article for full details on how this works.

    0 讨论(0)
提交回复
热议问题