Shared folder access with login & password impersonation - W2K8 IIS7

198 views Asked by At

Hope to get some help here.

I'm using impersonation to login to a shared folder and everything works locally (WIN8). It doens't work on a Win2K8 IIS7 server.

Following code is used for the impersonation:

public sealed class WrappedImpersonation
{
    public enum LogonType : int
    {
        Interactive = 2,
        Network = 3,
        Batch = 4,
        Service = 5,
        Unlock = 7,
        NetworkClearText = 8,
        NewCredentials = 9
    }

    public enum LogonProvider : int
    {
        Default = 0,  // LOGON32_PROVIDER_DEFAULT
        WinNT35 = 1,
        WinNT40 = 2,  // Use the NTLM logon provider.
        WinNT50 = 3   // Use the negotiate logon provider.
    }

    public enum ImpersonationLevel
    {
        SecurityAnonymous = 0,
        SecurityIdentification = 1,
        SecurityImpersonation = 2,
        SecurityDelegation = 3
    }

    [DllImport("advapi32.dll", EntryPoint = "LogonUserW", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain,
        String lpszPassword, LogonType dwLogonType, LogonProvider dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll")]
    public extern static bool CloseHandle(IntPtr handle);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);

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

    private string _domain, _password, _username;
    private IntPtr _token;
    private WindowsImpersonationContext _context;
    private IntPtr _duplicateToken;

    private bool IsInContext
    {
        get { return _context != null; }
    }

    public WrappedImpersonation(string domain, string username, string password)
    {
        _domain = String.IsNullOrEmpty(domain) ? "." : domain;
        _username = username;
        _password = password;
        _token = IntPtr.Zero;
    }

    // Changes the Windows identity of this thread. Make sure to always call Leave() at the end.
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public void Enter()
    {
        if (IsInContext)
            return;

        _token = IntPtr.Zero;
        bool logonSuccessfull = LogonUser(_username, _domain, _password, LogonType.NewCredentials, LogonProvider.WinNT50, ref _token);
        if (!logonSuccessfull)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        DuplicateToken(_token, (int)ImpersonationLevel.SecurityImpersonation, ref _duplicateToken);

        WindowsIdentity identity = new WindowsIdentity(_duplicateToken);
        _context = identity.Impersonate();

        Debug.WriteLine(WindowsIdentity.GetCurrent().Name);
    }

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public void Leave()
    {
        if (!IsInContext)
            return;

        _context.Undo();

        if (_token != IntPtr.Zero)
        {
            CloseHandle(_token);
        }
        _context = null;
    }

usage:

            var impersonationContext = new WrappedImpersonation(_url, _login, _password);
        impersonationContext.Enter();

        List<string> files = Directory.GetFiles(_dataSet.TransferMethod.URL).ToList();
  impersonationContext.Leave();

Server settings: Local Security Policy -> Local Policies -> User Rights Assignments -> Impersonate a client after authentication : does my AppPool Identity need to be added here?

Secondary Logon service is started.

Error code on server: System.UnauthorizedAccessException: Access to the path '\MyServer\MySharedFolder' is denied.

I've tried the WNetAddConnection2 methods, but these are not sufficient if you want to switch between shares because this blocks after a while.

Application: MVC.NET .NET version: 4.5

Did anybody got this to work on a Win2K8 IIS7 machine?

0

There are 0 answers