Копировать файлы через UNC

У меня есть сервер A, на котором размещено приложение для записи файлов на жесткий диск. У меня есть 2 других сервера B и C. B и C доступны через общие ресурсы UNC на A.

Я хочу, чтобы любые файлы, записанные на жесткий диск на A, копировались под аналогичную структуру каталогов на серверы B и C. Я пробовал использовать File.Copy, но это дает мне отказ в доступе каждый раз. Как мне настроить безопасность, чтобы это работало? Или есть способ выдать себя за пользователя?

Спасибо


person Gabbar    schedule 28.02.2013    source источник
comment
Возможный дубликат: stackoverflow.com/questions/2702109/ РЕДАКТИРОВАТЬ: неправильный вопрос отмечен как повторяющийся, но он показывает Ответьте как все-таки выдать себя за другое лицо.   -  person Eli Gassert    schedule 28.02.2013
comment
Не понимаю, почему этот вопрос был закрыт как не по теме. Это совершенно правильный вопрос о том, как аутентифицироваться с использованием сетевых учетных данных при доступе к общему ресурсу UNC. Я дал элегантный ответ ниже.   -  person Steven Padfield    schedule 06.03.2013


Ответы (3)


Если вы просто пытаетесь получить доступ к общему сетевому ресурсу, для которого требуются учетные данные, вы можете сделать следующее:

  1. Вызовите WinAPI LogonUser, чтобы получить токен сетевых учетных данных.
  2. Оберните токен в объект WindowsIdentity.
  3. Вызовите Impersonate в WindowsIdentity.
  4. Получите доступ к сетевому ресурсу.
  5. Удалите WindowsImpersonationContext и WindowsIdentity.
  6. Вызовите WinAPI CloseHandle.

Я создал одноразовый класс, реализующий это поведение.

...

    using (new NetworkImpersonationContext("domain", "username", "password"))
    {
        // access network here
    }

...

public class NetworkImpersonationContext : IDisposable
{
    private readonly WindowsIdentity _identity;
    private readonly WindowsImpersonationContext _impersonationContext;
    private readonly IntPtr _token;
    private bool _disposed;

    public NetworkImpersonationContext(string domain, string userName, string password)
    {
        if (!LogonUser(userName, domain, password, 9, 0, out _token))
            throw new Win32Exception();
        _identity = new WindowsIdentity(_token);
        try
        {
            _impersonationContext = _identity.Impersonate();
        }
        catch
        {
            _identity.Dispose();
            throw;
        }
    }

    #region IDisposable Members

    public void Dispose()
    {
        GC.SuppressFinalize(this);
        Dispose(true);
    }

    #endregion

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

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

    protected virtual void Dispose(bool disposing)
    {
        if (_disposed)
            return;
        _disposed = true;

        if (disposing)
        {
            _impersonationContext.Dispose();
            _identity.Dispose();
        }

        if (!CloseHandle(_token))
            throw new Win32Exception();
    }

    ~NetworkImpersonationContext()
    {
        Dispose(false);
    }
}
person Steven Padfield    schedule 28.02.2013

Я бы не стал пытаться решать эту проблему на C #. Уже существует множество продуктов для репликации файлов, включая репликацию DFS, которая встроен в Windows Server 2003 и новее.

person D Stanley    schedule 28.02.2013

Я бы не стал программировать систему безопасности для поддержки этого. Лучше всего настроить это с помощью Windows (при условии, что вы используете серверы Windows). Вам необходимо убедиться, что серверам B и C назначены права, позволяющие серверу A выполнять запись в общие ресурсы UNC.

На этом этапе, предполагая, что это Windows, вы можете назначить права для имени машины серверов B и C, или вы можете поместить серверы B и C в группу и назначить права этой группе на сервере A.

person Shan Plourde    schedule 28.02.2013