2011-11-14 112 views

回答

3

不,您無法檢測到客戶端上的用戶並冒充他們的帳戶。

可能的解決方法...

我不知道這是否會工作,我並不是說這是一個好主意,但如果你可以提示用戶輸入他們的憑據,可能能夠使用程序化模擬。這裏有一個類,你可以使用:

/// <summary> 
/// Leverages the Windows API (advapi32.dll) to programmatically impersonate a user. 
/// </summary> 
public class ImpersonationContext : IDisposable 
{ 
    #region constants 

    private const int LOGON32_LOGON_INTERACTIVE = 2; 
    private const int LOGON32_PROVIDER_DEFAULT = 0; 

    #endregion 

    #region global variables 

    private WindowsImpersonationContext impersonationContext; 
    private bool impersonating; 

    #endregion 

    #region unmanaged code 

    [DllImport("advapi32.dll")] 
    private 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)] 
    private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); 

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

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

    #endregion 

    #region constructors 

    public ImpersonationContext() 
    { 
     impersonating = false; 
    } 

    /// <summary> 
    /// Overloaded constructor and begins impersonating. 
    /// </summary> 
    public ImpersonationContext(string userName, string password, string domain) 
    { 
     this.BeginImpersonationContext(userName, password, domain); 
    } 

    #endregion 

    #region impersonation methods 

    /// <summary> 
    /// Begins the impersonation context for the specified user. 
    /// </summary> 
    /// <remarks>Don't call this method if you used the overloaded constructor.</remarks> 
    public void BeginImpersonationContext(string userName, string password, string domain) 
    { 
     //initialize token and duplicate variables 
     IntPtr token = IntPtr.Zero; 
     IntPtr tokenDuplicate = IntPtr.Zero; 

     if (RevertToSelf()) 
     { 
      if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
      { 
       if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
       { 
        using (WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate)) 
        { 
         //begin the impersonation context and mark impersonating true 
         impersonationContext = tempWindowsIdentity.Impersonate(); 
         impersonating = true; 
        } 
       } 
      } 
     } 

     //close the handle to the account token 
     if (token != IntPtr.Zero) 
      CloseHandle(token); 

     //close the handle to the duplicated account token 
     if (tokenDuplicate != IntPtr.Zero) 
      CloseHandle(tokenDuplicate); 
    } 

    /// <summary> 
    /// Ends the current impersonation context. 
    /// </summary> 
    public void EndImpersonationContext() 
    { 
     //if the context exists undo it and dispose of the object 
     if (impersonationContext != null) 
     { 
      //end the impersonation context and dispose of the object 
      impersonationContext.Undo(); 
      impersonationContext.Dispose(); 
     } 

     //mark the impersonation flag false 
     impersonating = false; 
    } 

    #endregion 

    #region properties 

    /// <summary> 
    /// Gets a value indicating whether the impersonation is currently active. 
    /// </summary> 
    public bool Impersonating 
    { 
     get 
     { 
      return impersonating; 
     } 
    } 

    #endregion 

    #region IDisposable implementation 

    ~ImpersonationContext() 
    { 
     Dispose(false); 
    } 

    public void Dispose() 
    { 
     Dispose(true);    
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (impersonationContext != null) 
      { 
       impersonationContext.Undo(); 
       impersonationContext.Dispose(); 
      } 
     } 
    } 

    #endregion  
} 

這裏是你如何實現類:

using (ImpersonationContext context = new ImpersonationContext("user", "password", "domain")) 
{ 
    if (context.Impersonating) 
    { 
     //impersonating 
    } 
} 
+0

如果用戶已經登錄in..this解決方案不起作用的網絡資源的權限。如果你想冒充另一個賬戶(即服務賬戶)......我更喜歡它。 –

+0

@請參閱(http://www.codeproject.com/KB/cs/zetaimpersonator.aspx) –

+1

@UweKeim:這與我上面的類似。 –

6

假設你在網站上使用Windows集成身份驗證,則可以使用用戶得到用戶的憑據。身份。

添加引用:

using System.Security.Principal; 

使用此模仿網絡上的當前用戶。

WindowsIdentity wi = (WindowsIdentity)User.Identity; 
WindowsImpersonationContext wic = null; 

try 
{ 
    wic = wi.Impersonate(); 

    if (wi.IsAuthenticated) 
    { 
     //Do stuff here on network as Current User 
     // i.e. asyncFileUpload.SaveAs(location); 
    } 

} 
catch(Exception ex) 
{ 
    //Log Error Here 

    if (wic != null) 
     wic.Undo(); 

    return; 
} 
finally 
{ 
    if (wic != null) 
     wic.Undo(); 
} 

確保登錄的用戶對他們將訪問

+1

只需要注意一下:你不需要在catch中使用'wic.Undo()'調用。 finally塊將在try塊成功完成或catch塊結束後運行。 – Joshua