RE: Anonymous access + Windows Authentication

From: Kevin Schlegelmilch (KevinSchlegelmilch_at_discussions.microsoft.com)
Date: 09/14/05


Date: Wed, 14 Sep 2005 13:59:06 -0700

Is this what you need?

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;

namespace Impersonate
{
        /// <summary>
        /// Summary description for ImpersonateUser.
        /// </summary>
        public class ImpersonateUser
        {

                [DllImport("advapi32.dll", SetLastError=true)]
                private static extern bool LogonUser(string lpszUsername,
                        string lpszDomain,
                        string lpszPassword,
                        int dwLogonType,
                        int dwLogonProvider,
                        ref IntPtr phToken);

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

                private WindowsImpersonationContext wic = null;
                private WindowsIdentity currentIdentity = null;

                public ImpersonateUser()
                {
                        // Get current Identity
                        currentIdentity = WindowsIdentity.GetCurrent();
                }

                /// <summary>
                /// This will impersonate a user using the LogonUser() and return a handle
                /// to the WindowsImpersonationContext
                /// </summary>
                /// <param name="login"></param>
                /// <param name="password"></param>
                /// <param name="domain"></param>
                public WindowsImpersonationContext Impersonate(string login, string
                        password, string domain)
                {
                        // constants used by LogonUser() method
                        const int LOGON32_LOGON_NETWORK = 3;
                        const int LOGON32_PROVIDER_DEFAULT = 0;
                        // handle returned from the LogonUser() method
                        IntPtr handle = new IntPtr(0);
                        handle = IntPtr.Zero;
                        // try to login to the domain
                        bool logonUser = LogonUser(login, domain, password,
                                LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
                        // login unsuccessful
                        if(!logonUser)
                        {
                                // get the error
                                int lastWin32Error = Marshal.GetLastWin32Error();
                                throw new Exception("ImpersonateUser failed<br>Win32Error: " +
                                        lastWin32Error);
                        }
                        // create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
                        WindowsIdentity wi
                                = new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
                        Thread.CurrentPrincipal = new WindowsPrincipal(wi);
                        wic = wi.Impersonate();
                        // close the handle
                        CloseHandle(handle);
                        // return the WindowsImpersonationContext
                        return wic;
                }

                public void Undo()
                {
                        // Impersonate back to original identity
                        Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
                        currentIdentity.Impersonate();
                }
                
        }

}