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

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

I would rather not create an impersonation of the entire site or configure a mapped drive on the server.

+1
source share
2 answers

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

Using:

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

the 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(); } } } 
+4
source

Actually the process is quite simple, you can use this code:

 using System.Security.Principal; ... // Obtain the authenticated user 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 is in the "Now impersonate" section. The KEY is the final unit, it is VERY important. You can view this MSDN article for full details on how this works.

+3
source

Source: https://habr.com/ru/post/1299767/


All Articles