2

我有一个服务器 A,它托管一个应用程序来将文件写入它的硬盘驱动器。我有另外 2 台服务器 B 和 C。A 上的 UNC 共享可以访问 B 和 C。

我希望将任何写入 A 上的硬盘驱动器的文件复制到与服务器 B 和 C 类似的目录结构下。我尝试使用 File.Copy ,但这每次都会给我一个拒绝访问。我将如何设置安全性以使其正常工作?或者有没有办法冒充用户?

谢谢

4

3 回答 3

10

如果您只是尝试访问需要凭据的网络共享,您可以执行以下操作:

  1. 调用 WinAPI LogonUser 以获取网络凭据令牌。
  2. 将令牌包装在 WindowsIdentity 对象中。
  3. 在 WindowsIdentity 上调用 Impersonate。
  4. 访问网络资源。
  5. 处置 WindowsImpersonationContext 和 WindowsIdentity。
  6. 调用 WinAPI CloseHandle。

I created a disposable class that implements this behavior.

...

    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 服务器)。您必须确保服务器 B 和 C 已分配权限以允许服务器 A 写入 UNC 共享。

此时,假设这是 Windows,您可以将权限分配给服务器 B 和 C 的机器名称,或者您可以将服务器 B 和 C 放入一个组,并在服务器 A 上为该组分配权限。

于 2013-02-28T19:59:25.830 回答