locked
When shall I use SafeWaitHandle? RRS feed

  • Question

  • Hi,

    My ASP.NET web application runs under local system user and it often needs to access resources such as network files. So, we are using impersonation (identity section in web.config). The problem is, for all new threads, we have to do the impersonation manually.

    I am using WindowsImpersonationContext to impersonate. My code looks like this (and works fine):

     

    /*** CODE START ***/

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.Web.Configuration;
    using System.Configuration;
    using System.ComponentModel;

    namespace Jeevan.Security
    {   
        public sealed class WindowsImpersonator : IDisposable
        {
            #region Construction/Instantiation

            public WindowsImpersonator ( string userName, string pwd, string domain )
            {
                BeginImpersonation(userName, pwd, domain);
            }

            #endregion Construction/Instantiation

            #region P/Invoke

            private IntPtr _Token = IntPtr.Zero;

            [DllImport("advapi32.dll", SetLastError = true)]
            static extern bool LogonUser (
              string principal,
              string authority,
              string password,
              LogonSessionType logonType,
              LogonProvider logonProvider,
              out IntPtr token );

            [DllImport("kernel32.dll", SetLastError = true)]
            static extern bool CloseHandle ( IntPtr handle );

            enum LogonSessionType : uint
            {
                Interactive = 2,
                Network,
                Batch,
                Service,
                NetworkCleartext = 8,
                NewCredentials
            }

            enum LogonProvider : uint
            {
                Default = 0,
                WinNT35,    
                WinNT40,    
                WinNT50     
            }

            #endregion P/Invoke

            #region Fields

            private WindowsImpersonationContext _Context = null;
           
            #endregion Fields

            private void BeginImpersonation ( string userName, string pwd, string domain )
            {
                _Token = IntPtr.Zero;
               
                try
                {
                    bool result = LogonUser(userName,
                                            domain,
                                            pwd,
                                            LogonSessionType.Network,
                                            LogonProvider.Default,
                                            out _Token);
                    if (result)
                    {
                        WindowsIdentity id = new WindowsIdentity(_Token);

                        // Begin impersonation
                        _Context = id.Impersonate();                   
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                catch(Exception ex)
                {
                    throw new ApplicationException(string.Format("BeginImpersonation failed for user {0}/{1}", userName, domain), ex);
                }
            }

            private void StopImpersonation ()
            {
                if (_Context != null)
                    _Context.Undo();
                if (_Token != IntPtr.Zero)
                    CloseHandle(_Token);
            }

            #region IDisposable Members

            public void Dispose ()
            {
                StopImpersonation();
            }

            #endregion
        }
    }

    /*** CODE END ***/

    Lately, I read about the SafeXXXHandle classes. I have tested my code using SafeWaitHandle instead of the raw Token. But, unfortunately, the constructor of WindowsIdentity class always expect a raw token. I can use DangerousGetHandle(), but how safe is this?

    All I want to know is, is there a better way to achieve the same as my code above? "Better" in terms of performance and reliability.

    Thanks in advance.

    -- Jeevan

     

     

     

    Wednesday, May 25, 2011 9:50 AM

Answers

  • DangerousGetHandle() is not 100% dangerous, it depends on how we use this method, anyway, to use this method safely, even an advanced user needs to take more careful.

     

    The CSImpersonateUser project of All-In-One Code Framework demonstrates an implementation of Windows Impersonation in C#/.NET, you may want to have a look.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by jj_tins Thursday, May 26, 2011 3:36 AM
    Thursday, May 26, 2011 2:23 AM

All replies