Олицетворение с помощью Win32 API для доступа к общему сетевому ресурсу вместо чтения сетевого ресурса с помощью проводника Windows?

У меня есть веб-приложение, которое имитирует использование Win32 API. Я недавно вернулся из поездки и обнаружил, что та часть приложения, которая имитирует себя, не работает.

Причина олицетворения заключается в том, что существует общий сетевой ресурс, который используется для определенной цели. Когда мое веб-приложение обращается к этому сетевому ресурсу, оно должно выдавать себя за специальную учетную запись. Для обсуждения, uid - «Bob», пароль - «1234», а домен - «home».

Две недели назад я написал свою программу для использования Win32 API, чтобы выдать себя за Боба, и все было хорошо. Теперь Win32 API указывает на ошибку входа в систему. Мне сложно понять, что могло измениться. Чтобы быть точным, сервер указывает, что он не может выдать себя за Боба. Ошибка возникает до того, как сервер фактически попытается получить доступ к общему сетевому ресурсу.

Странно то, что если я подключаюсь к своему веб-серверу с помощью MSTSC, я могу щелкнуть «Подключить сетевой диск» в проводнике Windows и получить доступ к файлам, используя Bob @ home и пароль 1234. (Я ввожу идентификатор пользователя и пароль. нажав «Подключиться, используя другое имя пользователя» в диалоговом окне «Подключить сетевой диск»)

Кажется, что что-то другое должно происходить, когда я пытаюсь получить доступ к своему сетевому ресурсу с олицетворением, а не с помощью проводника Windows.

В чем разница?

Обновление: мне кажется, что ответ на эту проблему заключается в том, что существует какое-то разрешение на вход в систему, которому отказывают, но почему-то не задействованы, когда я получаю доступ к своим файлам через проводник Windows.


person Vivian River    schedule 17.10.2011    source источник
comment
Вы спрашиваете, в чем разница между доступом к общему ресурсу через олицетворение и доступом к нему через проводник Windows из вашей учетной записи на вашем компьютере? Вы можете разместить код?   -  person James Johnson    schedule 17.10.2011
comment
Я спрашиваю, в чем разница между доступом к общему ресурсу посредством имитации и доступом к нему через проводник Windows с той же учетной записью, которая использовалась для олицетворения.   -  person Vivian River    schedule 17.10.2011
comment
Вы проверили права доступа к общему ресурсу? Я предполагаю, что вы указали разрешения для папки, но многие люди забывают применить разрешения к общему ресурсу.   -  person James Johnson    schedule 17.10.2011
comment
Да, разрешения проверены. Я могу получить доступ к папке из любой точки сети; Я просто не могу получить к нему доступ через выдачу себя за другое лицо.   -  person Vivian River    schedule 17.10.2011
comment
Вы указываете домен в телефонном коде?   -  person Josh    schedule 17.10.2011
comment
Как вы пытаетесь получить доступ к общей папке? Вы правильно используете UNC-путь?   -  person James Johnson    schedule 17.10.2011
comment
Да, я использую UNC-путь и указываю домен   -  person Vivian River    schedule 17.10.2011
comment
msdn.microsoft.com / en-us / library / Убедитесь, что у вас есть уровень делегата.   -  person thangcao    schedule 08.07.2014


Ответы (1)


Убедитесь, что вы используете UNC-путь для доступа к папке:

string path = @"\\server\folder";

Я не знаю, как выглядит ваш класс олицетворения, но вот класс, который я использую для аналогичных задач:

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

Использование ImpersonationContext:

using (ImpersonationContext context = new ImpersonationContext("user", "password", "domain")) 
{ 
    if (context.Impersonating) 
    { 
        Process.Start(@"/Support/SendFax/SendFax.exe"); 
    } 
} 
person James Johnson    schedule 17.10.2011
comment
Мой код очень похож на ваш. Проблема в том, что мой код работал, но больше не работает. - person Vivian River; 17.10.2011
comment
@RiceFlourCookies: Это может указывать на изменение разрешений где-то. Вы пытались временно предоставить неограниченный доступ к папке, т.е. предоставить всем полные разрешения? - person James Johnson; 17.10.2011
comment
Когда я запускаю свой код через отладчик, он терпит неудачу, когда пытается начать олицетворение. В частности, возникает исключение до того, что сервер даже попытается получить доступ к общему сетевому ресурсу. - person Vivian River; 17.10.2011
comment
Хм ... а вы уверены, что учетная запись пользователя активна? Ваш код вызывает RevertToSelf() перед олицетворением пользователя? - person James Johnson; 17.10.2011
comment
Да, он вызывает RevertToSelf (). Я также обнаружил, что код работает, когда он запускается в Casini на моей локальной рабочей станции. Однако он не работает как на моих веб-серверах разработки, так и на рабочих. - person Vivian River; 17.10.2011