非域Windows环境中的C#编程远程文件夹/文件身份验证

非域Windows环境中的C#编程远程文件夹/文件身份验证,c#,windows,authentication,fileshare,workgroup,C#,Windows,Authentication,Fileshare,Workgroup,在非域环境中尝试在远程计算机上读写文件时,我需要能够以编程方式进行身份验证 当您在Windows运行提示符中键入类似于\\targetComputer\C$\targetFolder或\\targetComputer\admin$的命令(其中目标计算机不在域中)时,系统将提示您输入用户名和密码。输入用户名和密码后,您就可以完全访问远程文件夹 如何在C#中以编程方式完成此身份验证 我试过了 --模拟,但它似乎只在域环境中工作 --CMDKEY.exe,但它似乎也只在域环境中工作 一定有办法做到这一

在非域环境中尝试在远程计算机上读写文件时,我需要能够以编程方式进行身份验证

当您在Windows运行提示符中键入类似于\\targetComputer\C$\targetFolder或\\targetComputer\admin$的命令(其中目标计算机不在域中)时,系统将提示您输入用户名和密码。输入用户名和密码后,您就可以完全访问远程文件夹

如何在C#中以编程方式完成此身份验证

我试过了

--模拟,但它似乎只在域环境中工作

--CMDKEY.exe,但它似乎也只在域环境中工作

一定有办法做到这一点,但到目前为止,我到处寻找,运气都不好。也许我只是找错东西了?我肯定我不是第一个提出这个问题的人。任何帮助都将不胜感激

谢谢

编辑:


我想我只是找到了一个不同的帖子来回答我的问题:

我现在会用它,看看它能给我带来什么


谢谢

模拟也适用于对等/LAN网络。我得到了典型的家庭网络,其中一些机器在默认的“工作组”上,如果我记得在安装时这样做的话,一些机器在指定的工作组上

以下是我使用IIS服务器应用程序访问其他计算机上的文件的代码(无需在涉及的两台计算机上使用相同的用户和密码,从某处复制并修改以供我使用):


我想我刚刚发现了一个不同的SO帖子,它回答了我的问题:使用凭据从远程、不受信任的域访问共享文件(UNC),我现在将使用它,看看它能给我带来什么。谢谢我能够使用以下代码来解决我的问题:。然而,我很想稍后测试你的代码(我想我可能真的…感觉我在发布这个问题之前看到了那段代码),看看它与我最初的模拟代码相比如何。您的代码的第一眼看上去就像我以前使用的代码,只在域环境中取得了成功。稍后我会更仔细地研究它。谢谢。密钥是:LOGON32\u LOGON\u NEW\u凭据。我尝试了所有不同的选择,而LOGON32\u LOGON\u NEW\u凭证才有效。其余的代码是通用的,非常有趣。我一定会尝试一下,然后回来汇报。谢谢虽然我正在解决一个稍微不同的问题,但这段代码对我来说也很有效。我的目标是访问网络文件夹中的文件,该文件夹使用的域与我的本地计算机不同。令人惊讶的是,尽管有dll导入,它还是开箱即用!我忘了汇报,只是想说这段代码似乎工作得很好。再次感谢!
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.ComponentModel;

/// <summary>
/// Class to impersonate another user. Requires user, pass and domain/computername
/// All code run after impersonationuser has been run will run as this user.
/// Remember to Dispose() afterwards.
/// </summary>
public class ImpersonateUser:IDisposable {

    private WindowsImpersonationContext LastContext = null;
    private IntPtr LastUserHandle = IntPtr.Zero;

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

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool ImpersonateLoggedOnUser(int Token);

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

    [DllImport("kernel32.dll")]
    public static extern Boolean CloseHandle(IntPtr hObject);

    public const int LOGON32_PROVIDER_DEFAULT = 0;
    public const int LOGON32_PROVIDER_WINNT35 = 1;
    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_LOGON_NETWORK = 3;
    public const int LOGON32_LOGON_BATCH = 4;
    public const int LOGON32_LOGON_SERVICE = 5;
    public const int LOGON32_LOGON_UNLOCK = 7;
    public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;// Win2K or higher
    public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;// Win2K or higher
    #endregion

    public ImpersonateUser(string username, string domainOrComputerName, string password, int nm = LOGON32_LOGON_NETWORK) {

        IntPtr userToken = IntPtr.Zero;
        IntPtr userTokenDuplication = IntPtr.Zero;

        bool loggedOn = false;

        if (domainOrComputerName == null) domainOrComputerName = Environment.UserDomainName;

        if (domainOrComputerName.ToLower() == "nt authority") {
            loggedOn = LogonUser(username, domainOrComputerName, password, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, out userToken);
        } else {
            loggedOn = LogonUser(username, domainOrComputerName, password, nm, LOGON32_PROVIDER_DEFAULT, out userToken);
        }

        WindowsImpersonationContext _impersonationContext = null;
        if (loggedOn) {
            try {
                // Create a duplication of the usertoken, this is a solution
                // for the known bug that is published under KB article Q319615.
                if (DuplicateToken(userToken, 2, ref userTokenDuplication)) {
                    // Create windows identity from the token and impersonate the user.
                    WindowsIdentity identity = new WindowsIdentity(userTokenDuplication);
                    _impersonationContext = identity.Impersonate();
                } else {
                    // Token duplication failed!
                    // Use the default ctor overload
                    // that will use Mashal.GetLastWin32Error();
                    // to create the exceptions details.
                    throw new Win32Exception();
                }
            } finally {
                // Close usertoken handle duplication when created.
                if (!userTokenDuplication.Equals(IntPtr.Zero)) {
                    // Closes the handle of the user.
                    CloseHandle(userTokenDuplication);
                    userTokenDuplication = IntPtr.Zero;
                }

                // Close usertoken handle when created.
                if (!userToken.Equals(IntPtr.Zero)) {
                    // Closes the handle of the user.
                    CloseHandle(userToken);
                    userToken = IntPtr.Zero;
                }
            }
        } else {
            // Logon failed!
            // Use the default ctor overload that 
            // will use Mashal.GetLastWin32Error();
            // to create the exceptions details.
            throw new Win32Exception();
        }

        if (LastContext == null) LastContext = _impersonationContext;
    }

    public void Dispose() {
        LastContext.Undo();
        LastContext.Dispose();
    }
}
using (var impersonation = new ImpersonateUser("OtherMachineUser", "OtherMachineName", "Password", LOGON32_LOGON_NEW_CREDENTIALS))
    {
        var files = System.IO.Directory.GetFiles("\\OtherMachineName\fileshare");
    }