2009-05-18 7 views

답변

4

Michiel van Otegem: WindowsImpersonationContext made easy 코드를 사용하고 IDisposable 구현을 추가했습니다. 나는 another question about impersonation in ASP.NET에서 이것을 발견했습니다.

사용법 :

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

코드 :

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(); 
     } 
    } 
} 
+1

개인적으로 dllimports 및 기타 항목이 있기 때문에 개인적으로, 나는이 팬이 아니며, 전반적으로 그것을하지 않고 얻을 수 있습니다. –

3

사실, 프로세스가이 같은 코드를 사용할 수 있습니다, 매우 간단합니다;

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 

코드가 '지금 가장 한 것'섹션에 포함됩니다. KEY가 finally 블록입니다. 이것은 매우 중요합니다. 이 방법에 대한 자세한 내용은 MSDN 문서를 참조하십시오.

+0

도메인, 사용자 이름 및 암호를 전달하여 사용할 수도 있습니까? –

+0

예, 새 Windows ID를 만들어야합니다. –

관련 문제