LogonUser and delegation

前端 未结 2 1218
情歌与酒
情歌与酒 2020-12-11 07:34

I\'m using the LogonUser win32 api:

token = LogonUser(...)
WindowsIdentity newId = new WindowsIdentity(token);            
WindowsImpersonationContext impers         


        
2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-11 08:05

    I don't know if this will work for WCF. But we use it in our production web app for impersonation to read and write files to the file system. You will need to define the API's for AdvApi32.LogonUser, AdvApi32.DuplicateToken, and Kernel32.CloseHandle and make sure to Close the WindowsImpersonationContext when you are done.

        /// impersonates a user
        /// domain\name of the user account
        /// the user's password
        /// the new WindowsImpersonationContext
        public static WindowsImpersonationContext ImpersonateUser(String username, String password)
        {
            WindowsIdentity winId = WindowsIdentity.GetCurrent();
            if (winId != null)
            {
                if (string.Compare(winId.Name, username, true) == 0)
                {
                    return null;
                }
            }
    
            //define the handles
            IntPtr existingTokenHandle = IntPtr.Zero;
            IntPtr duplicateTokenHandle = IntPtr.Zero;
    
            String domain;
            if (username.IndexOf("\\") > 0)
            {
                //split domain and name
                String[] splitUserName = username.Split('\\');
                domain = splitUserName[0];
                username = splitUserName[1];
            }
            else
            {
                domain = String.Empty;
            }
    
            try
            {
                //get a security token
    
                bool isOkay = AdvApi32.LogonUser(username, domain, password,
                    (int) AdvApi32.LogonTypes.LOGON32_LOGON_INTERACTIVE,
                    (int) AdvApi32.LogonTypes.LOGON32_PROVIDER_DEFAULT,
                    ref existingTokenHandle);
    
                if (!isOkay)
                {
                    int lastWin32Error = Marshal.GetLastWin32Error();
                    int lastError = Kernel32.GetLastError();
    
                    throw new Exception("LogonUser Failed: " + lastWin32Error + " - " + lastError);
                }
    
                // copy the token
    
                isOkay = AdvApi32.DuplicateToken(existingTokenHandle,
                    (int) AdvApi32.SecurityImpersonationLevel.SecurityImpersonation,
                    ref duplicateTokenHandle);
    
                if (!isOkay)
                {
                    int lastWin32Error = Marshal.GetLastWin32Error();
                    int lastError = Kernel32.GetLastError();
                    Kernel32.CloseHandle(existingTokenHandle);
                    throw new Exception("DuplicateToken Failed: " + lastWin32Error + " - " + lastError);
                }
                // create an identity from the token
    
                WindowsIdentity newId = new WindowsIdentity(duplicateTokenHandle);
                WindowsImpersonationContext impersonatedUser = newId.Impersonate();
    
                return impersonatedUser;
            }
            finally
            {
                //free all handles
                if (existingTokenHandle != IntPtr.Zero)
                {
                    Kernel32.CloseHandle(existingTokenHandle);
                }
                if (duplicateTokenHandle != IntPtr.Zero)
                {
                    Kernel32.CloseHandle(duplicateTokenHandle);
                }
            }
        }
    

提交回复
热议问题