2

ハードドライブにファイルを書き込むアプリをホストするサーバーAがあります。他に 2 つのサーバー B と C があります。B と C には、A の UNC 共有からアクセスできます。

A のハード ドライブに書き込まれたファイルを、同様のディレクトリ構造でサーバー B および C にコピーする必要があります。File.Copy を使用してみましたが、毎回アクセスが拒否されます。これを機能させるには、どのようにセキュリティを設定しますか? または、ユーザーになりすます方法はありますか?

ありがとう

4

3 に答える 3

10

資格情報を必要とするネットワーク共有にアクセスしようとしているだけの場合は、次の操作を実行できます。

  1. WinAPI LogonUser を呼び出して、ネットワーク資格情報トークンを取得します。
  2. トークンを WindowsIdentity オブジェクトにラップします。
  3. WindowsIdentity で Impersonate を呼び出します。
  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);
    }
}
于 2013-02-28T21:29:15.580 に答える
2

私は C# でこれに取り組もうとはしません。Windows Server 2003 以降に組み込まれているDFS レプリケーションなど、既に多数のファイル レプリケーション製品が販売されています。

于 2013-02-28T19:58:42.910 に答える
0

これをサポートするようにセキュリティをプログラムしようとはしません。最善の策は、Windows を使用してこれを構成することです (Windows サーバーを使用していると仮定します)。サーバー A が UNC 共有に書き込むことができるように、サーバー B と C に権限が割り当てられていることを確認する必要があります。

その時点で、これが Windows であると仮定すると、サーバー B と C のマシン名に権限を割り当てるか、サーバー B と C をグループに入れ、サーバー A のそのグループに権限を割り当てることができます。

于 2013-02-28T19:59:25.830 に答える