Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set ASP.NET security impersonation

I am going through

http://www.codeassociate.com/caapi/html/T_CA_Common_Security_Impersonate.htm

I don't want to hard-code domain\username and password.

Is it possible to get the current Windows user credentials and pass it?

like image 522
user415772 Avatar asked Nov 14 '11 14:11

user415772


People also ask

How do you set system Web identity impersonate is set to true?

web/identity@impersonate is set to true. Things you can try: If the application supports it, disable client impersonation. If you are certain that it is OK to ignore this error, it can be disabled by setting system. webServer/validation@validateIntegratedModeConfiguration to false.


2 Answers

Assuming you're using Windows Integrated Authentication on the site, you can get the User's credentials using User.Identity.

Add reference:

using System.Security.Principal;

Use this to impersonate the current user on the network.

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

Make sure the logged-in user has permission on the network resource they'll be accessing

like image 196
Ed B Avatar answered Oct 07 '22 14:10

Ed B


No, you can't detect the user on the client and impersonate their account.

A possible workaround...

I don't know if this would work, and I'm not saying that it's a good idea, but if you can prompt the user for their credentials, you might be able to use programmatic impersonation. Here's a class that you can use:

/// <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    
}

Here's how you implement the class:

using (ImpersonationContext context = new ImpersonationContext("user", "password", "domain")) 
{ 
    if (context.Impersonating) 
    { 
        //impersonating
    } 
}
like image 26
James Johnson Avatar answered Oct 07 '22 13:10

James Johnson