简体   繁体   English

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

[英]C# Programmatic Remote Folder / File Authentication In Non-Domain Windows Environment

I need to be able to programmatically authenticate when trying to read and write files on a remote computer in a non-domain environment. 在非域环境中尝试在远程计算机上读写文件时,我需要能够以编程方式进行身份验证。

When you type a command into the Windows RUN prompt that is similar to \\\\targetComputer\\C$\\targetFolder or \\\\targetComputer\\admin$, where the targetComputer is NOT on a domain, you will be prompted to enter a username and password. 当您在Windows RUN提示符下键入与\\\\ targetComputer \\ C $ \\ targetFolder或\\\\ targetComputer \\ admin $相似的命令时,targetComputer不在域中,将提示您输入用户名和密码。 Once you enter the username and password, you have full access to the remote folder. 输入用户名和密码后,您就可以完全访问远程文件夹。

How can I accomplish this authentication programmatically in C#? 如何在C#中以编程方式完成此身份验证?

I've tried.. 我试过了..

--Impersonation, but it appears to only work in a domain environment. -模拟,但它似乎仅在域环境中有效。

--CMDKEY.exe, but it also seems to only work in a domain environment. --CMDKEY.exe,但它似乎也只能在域环境中工作。

There must be a way to do this, but I have searched high and low with no luck so far. 一定有办法做到这一点,但是到目前为止,我一直没有走运。 Maybe I'm just looking for the wrong thing? 也许我只是在找错东西? I'm sure I'm not the first to have this question. 我敢肯定我不是第一个提出这个问题的人。 Any help would be greatly appreciated. 任何帮助将不胜感激。

Thanks! 谢谢!

EDIT : 编辑:

I think I just found a different SO posting that answers my question: Accessing a Shared File (UNC) From a Remote, Non-Trusted Domain With Credentials 我想我刚刚找到了一条不同的SO帖子,该帖子回答了我的问题: 使用凭据从远程,非受信任的域访问共享文件(UNC)

I will work with that for now and see where it gets me. 我现在将使用它,看看它能帮助我什么。

Thanks! 谢谢!

Impersonation works with Peer/LAN network as well. 模拟也可用于Peer / LAN网络。 I got your typical home network with some machines on default "Workgroup" and some on a named one if I remembered doing it on the install. 我有一个典型的家庭网络,其中有些机器位于默认的“工作组”上,有些则位于一个命名的机器上(如果我记得在安装过程中这样做过)。

Here is the code I use from my IIS server app to access files on my other computer (without having to have the same user and password on both machines involved, copied from somewhere and modified for my use): 这是我在IIS服务器应用程序中用来访问另一台计算机上的文件的代码(不必在所涉及的两台计算机上都具有相同的用户名和密码,可以从某个地方复制并修改以供我使用):

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();
    }
}

The specific code I found out worked after a bit of trying was this: 经过一番尝试后,我发现特定的代码有效:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Windows身份验证从非域计算机访问SQL Server 2005 - Access to SQL Server 2005 from a non-domain machine using Windows authentication Windows Forms 来自非域添加机器的模拟 - Windows Forms Impersonation from a non-Domain added machine C#ActiveDirectory - 如何从已加入域的计算机远程添加本地用户帐户到非域计算机 - C# ActiveDirectory - How do I add a local user account remotely from a domain-joined machine to a non-domain machine 使用 C# 将文件保存在远程计算机的文件夹或共享文件夹中。 远程机器在另一个域中 - Use C# to save a file in a folder or shared folder in a remote machine. The remote machine is in another domain C#非Windows远程桌面 - C# Non-Windows Remote Desktop 无法在非域上访问服务Windows 7自托管WCF应用程序 - Can't access service Windows 7 self-hosted WCF app on a non-domain 在Windows域用户环境中通过代理进行POST时,C#中的Fluent出现(407)代理身份验证必需错误 - Flurl in C# get (407) Proxy Authentication Required error when POST via proxy in Windows Domain User environment 在非域计算机上使用域控制器以编程方式同步时间 - programmatically sync time on non-domain machine with domain controller 如何在非域xp计算机上与域控制器同步时间? - how to sync time on a non-domain xp computer with domain controller? 从非域计算机连接到域SQL Server 2005 - Connect to domain SQL Server 2005 from non-domain machine
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM