使用用户名和密码连接到网络驱动器

Posted

技术标签:

【中文标题】使用用户名和密码连接到网络驱动器【英文标题】:Connect to network drive with user name and password 【发布时间】:2011-04-11 16:20:50 【问题描述】:

如何提供凭据以便我可以连接到 .NET 中的网络驱动器?

我正在尝试从网络驱动器中检索文件,并且需要提供用户凭据才能访问该驱动器。

【问题讨论】:

我相信还有更通用的方式:***.com/questions/295538/… 【参考方案1】:

非常优雅的解决方案灵感来自this one。这个只使用 .Net 库,不需要使用任何命令行或 Win32 API。

供参考的代码:

NetworkCredential theNetworkCredential = new NetworkCredential(@"domain\username", "password");
CredentialCache theNetCache = new CredentialCache();
theNetCache.Add(new Uri(@"\\computer"), "Basic", theNetworkCredential);
string[] theFolders = Directory.GetDirectories(@"\\computer\share");

【讨论】:

@VladL 您可以使用 Windows 资源管理器手动访问网络共享吗?您对用户有必要的权限吗? 我必须对此进行两次更改才能使其在我的网络上运行。我必须使用具有不同域参数的 NetworkCredential 重载。我不得不从 Basic 切换到 Digest。 我觉得奇怪的是,我们 1) 创建了一个 CredentialsCache 实例,并且 2) 实际上没有将该对象用于任何事情。如果这是某个全球商店(我们所有的操作都会自动命中),我希望会获得一些单身人士。由于我们不是,我认为我们实际上并没有在这里使用凭据来产生任何影响。 我得到了误报。它起作用了,因为我映射了共享。一旦它消失了,我就开始被拒绝异常。 在某些情况下需要指定域。例如域不同的地方。添加到答案中,【参考方案2】:

最好的方法是 p/invoke WNetUseConnection。

[StructLayout(LayoutKind.Sequential)] 
private class NETRESOURCE
 
        public int dwScope = 0;
        public int dwType = 0;
        public int dwDisplayType = 0;
        public int dwUsage = 0;
        public string lpLocalName = "";
        public string lpRemoteName = "";
        public string lpComment = "";
        public string lpProvider = "";



[DllImport("Mpr.dll")] 
private static extern int WNetUseConnection(
            IntPtr hwndOwner,
            NETRESOURCE lpNetResource,
            string lpPassword,
            string lpUserID,
            int dwFlags,
            string lpAccessName,
            string lpBufferSize,
            string lpResult
        );

Example code here.

【讨论】:

它对我不起作用。连接没有错误,但是访问文件夹时,程序永远卡住了【参考方案3】:

您可以使用WindowsIdentity 类(带有logon token)在读取和写入文件时进行模拟。

var windowsIdentity = new WindowsIdentity(logonToken);
using (var impersonationContext = windowsIdentity.Impersonate()) 
    // Connect, read, write

【讨论】:

仅适用于 Windows 环境。当您开始使用 AS400、Solaris 和 Linux 时,它会变得很麻烦,尤其是当共享需要一个不同于您运行应用程序的凭证时。 bzlm 的解决方案有效,但他并没有真正充实它。 Get some code from msdn.microsoft.com/en-us/library/…, namely the safeTokenHandle class and dependencies. 此代码在本地系统上运行,但在具有匿名池标识的 IIS 上无法运行,有什么建议吗?【参考方案4】:

我真的不知道隐藏的过程,但我使用 webrequest,这样我就能够传递凭据,它对我来说非常有效。

var ftpDownloadFile = WebRequest.Create("filePath");
ftpDownloadFile.Method = WebRequestMethods.Ftp.DownloadFile;
ftpDownloadFile.Credentials = new NetworkCredential("user", "pass");
using (var reader = (FtpWebResponse)ftpDownloadFile.GetResponse())
using (var responseStream = reader.GetResponseStream())

    var writeStream = new FileStream(Path.Combine(LocalStorage), FileMode.Create);
    const int length = 2048;
    var buffer = new Byte[length];
    if (responseStream != null)
    
        var bytesRead = responseStream.Read(buffer, 0, length);
        while (bytesRead > 0)
        
            writeStream.Write(buffer, 0, bytesRead);
            bytesRead = responseStream.Read(buffer, 0, length);
        
    
    reader.Close();
    writeStream.Close();

【讨论】:

【参考方案5】:
var fileName = "Mylogs.log";
var local = Path.Combine(@"C:\TempLogs", fileName);
var remote = Path.Combine(@"\\servername\c$\Windows\Temp\", fileName);

WebClient request = new WebClient();
request.Credentials = new NetworkCredential(@"username", "password");

if (File.Exists(local))

    File.Delete(local);

    File.Copy(remote, local, true);

else

    File.Copy(remote, local, true);

【讨论】:

【参考方案6】:

将此代码用于在 MVC.NET 中测试的模拟,也许对于 dot net core 它需要一些更改,如果你想 dot net core 请告诉我,我会分享。

 public static class ImpersonationAuthenticationNew
    
        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool LogonUser(string usernamee, string domain, string password, LogonType dwLogonType, LogonProvider dwLogonProvider, ref IntPtr phToken);
        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr hObject);
        public static bool Login(string domain,string username, string password)
                        
            IntPtr token = IntPtr.Zero;
            var IsSuccess = LogonUser(username, domain, password, LogonType.LOGON32_LOGON_NEW_CREDENTIALS, LogonProvider.LOGON32_PROVIDER_WINNT50, ref token);
            if (IsSuccess)
            
                using (WindowsImpersonationContext person = new WindowsIdentity(token).Impersonate())
                
                    var xIdentity = WindowsIdentity.GetCurrent();
                    #region Start ImpersonationContext  Scope
                    try
                    

                        // TYPE YOUR CODE HERE 

                    
                    catch (Exception ex)  throw (ex); 
                    finally 
                        person.Undo();
                        CloseHandle(token);
                        return true;
                    
                    #endregion
                
            
            return false;
        
    

    #region Enums
    public enum LogonType
    
        /// <summary>
        /// This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
        /// by a terminal server, remote shell, or similar process.
        /// This logon type has the additional expense of caching logon information for disconnected operations;
        /// therefore, it is inappropriate for some client/server applications,
        /// such as a mail server.
        /// </summary>
        LOGON32_LOGON_INTERACTIVE = 2,

        /// <summary>
        /// This logon type is intended for high performance servers to authenticate plaintext passwords.

        /// The LogonUser function does not cache credentials for this logon type.
        /// </summary>
        LOGON32_LOGON_NETWORK = 3,

        /// <summary>
        /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without
        /// their direct intervention. This type is also for higher performance servers that process many plaintext
        /// authentication attempts at a time, such as mail or Web servers.
        /// The LogonUser function does not cache credentials for this logon type.
        /// </summary>
        LOGON32_LOGON_BATCH = 4,

        /// <summary>
        /// Indicates a service-type logon. The account provided must have the service privilege enabled.
        /// </summary>
        LOGON32_LOGON_SERVICE = 5,

        /// <summary>
        /// This logon type is for GINA DLLs that log on users who will be interactively using the computer.
        /// This logon type can generate a unique audit record that shows when the workstation was unlocked.
        /// </summary>
        LOGON32_LOGON_UNLOCK = 7,

        /// <summary>
        /// This logon type preserves the name and password in the authentication package, which allows the server to make
        /// connections to other network servers while impersonating the client. A server can accept plaintext credentials
        /// from a client, call LogonUser, verify that the user can access the system across the network, and still
        /// communicate with other servers.
        /// NOTE: Windows NT:  This value is not supported.
        /// </summary>
        LOGON32_LOGON_NETWORK_CLEARTEXT = 8,

        /// <summary>
        /// This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
        /// The new logon session has the same local identifier but uses different credentials for other network connections.
        /// NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
        /// NOTE: Windows NT:  This value is not supported.
        /// </summary>
        LOGON32_LOGON_NEW_CREDENTIALS = 9,
    
    public enum LogonProvider
    
        /// <summary>
        /// Use the standard logon provider for the system.
        /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name
        /// is not in UPN format. In this case, the default provider is NTLM.
        /// NOTE: Windows 2000/NT:   The default security provider is NTLM.
        /// </summary>
        LOGON32_PROVIDER_DEFAULT = 0,
        LOGON32_PROVIDER_WINNT35 = 1,
        LOGON32_PROVIDER_WINNT40 = 2,
        LOGON32_PROVIDER_WINNT50 = 3
    
    #endregion

【讨论】:

【参考方案7】:

将此代码用于在 MVC.NET 中测试的模拟,也许对于 dot net core 它需要一些更改,如果你想 dot net core 请告诉我,我会分享。

 public static class ImpersonationAuthenticationNew
    
        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool LogonUser(string usernamee, string domain, string password, LogonType dwLogonType, LogonProvider dwLogonProvider, ref IntPtr phToken);
        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr hObject);
        public static bool Login(string domain,string username, string password)
                        
            IntPtr token = IntPtr.Zero;
            var IsSuccess = LogonUser(username, domain, password, LogonType.LOGON32_LOGON_NEW_CREDENTIALS, LogonProvider.LOGON32_PROVIDER_WINNT50, ref token);
            if (IsSuccess)
            
                using (WindowsImpersonationContext person = new WindowsIdentity(token).Impersonate())
                
                    var xIdentity = WindowsIdentity.GetCurrent();
                    #region Start ImpersonationContext  Scope
                    try
                    

                        // TYPE YOUR CODE HERE 
                      return true;
                    
                    catch (Exception ex)  throw (ex); 
                    finally 
                        person.Undo();
                        CloseHandle(token);
                       
                    
                    #endregion
                
            
            return false;
        
    

    #region Enums
    public enum LogonType
    
        /// <summary>
        /// This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
        /// by a terminal server, remote shell, or similar process.
        /// This logon type has the additional expense of caching logon information for disconnected operations;
        /// therefore, it is inappropriate for some client/server applications,
        /// such as a mail server.
        /// </summary>
        LOGON32_LOGON_INTERACTIVE = 2,

        /// <summary>
        /// This logon type is intended for high performance servers to authenticate plaintext passwords.

        /// The LogonUser function does not cache credentials for this logon type.
        /// </summary>
        LOGON32_LOGON_NETWORK = 3,

        /// <summary>
        /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without
        /// their direct intervention. This type is also for higher performance servers that process many plaintext
        /// authentication attempts at a time, such as mail or Web servers.
        /// The LogonUser function does not cache credentials for this logon type.
        /// </summary>
        LOGON32_LOGON_BATCH = 4,

        /// <summary>
        /// Indicates a service-type logon. The account provided must have the service privilege enabled.
        /// </summary>
        LOGON32_LOGON_SERVICE = 5,

        /// <summary>
        /// This logon type is for GINA DLLs that log on users who will be interactively using the computer.
        /// This logon type can generate a unique audit record that shows when the workstation was unlocked.
        /// </summary>
        LOGON32_LOGON_UNLOCK = 7,

        /// <summary>
        /// This logon type preserves the name and password in the authentication package, which allows the server to make
        /// connections to other network servers while impersonating the client. A server can accept plaintext credentials
        /// from a client, call LogonUser, verify that the user can access the system across the network, and still
        /// communicate with other servers.
        /// NOTE: Windows NT:  This value is not supported.
        /// </summary>
        LOGON32_LOGON_NETWORK_CLEARTEXT = 8,

        /// <summary>
        /// This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
        /// The new logon session has the same local identifier but uses different credentials for other network connections.
        /// NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
        /// NOTE: Windows NT:  This value is not supported.
        /// </summary>
        LOGON32_LOGON_NEW_CREDENTIALS = 9,
    
    public enum LogonProvider
    
        /// <summary>
        /// Use the standard logon provider for the system.
        /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name
        /// is not in UPN format. In this case, the default provider is NTLM.
        /// NOTE: Windows 2000/NT:   The default security provider is NTLM.
        /// </summary>
        LOGON32_PROVIDER_DEFAULT = 0,
        LOGON32_PROVIDER_WINNT35 = 1,
        LOGON32_PROVIDER_WINNT40 = 2,
        LOGON32_PROVIDER_WINNT50 = 3
    
    #endregion

【讨论】:

【参考方案8】:

您可以使用 system.diagnostocs.process 调用“net use .... with userid and password”或使用这些命令的 shell。

【讨论】:

你可以,但你愿意吗? 如果它实现了您的用例的目标,那为什么不呢,那么它是完全有效的。它的一行代码可以达到预期的结果。它内置了所有错误处理功能,并且经过了测试。重写功能似乎很愚蠢。 “如果它达到了你的用例的目标,那么它是完全有效的”——这是一个非常笼统的说法,你的回答在我看来是一个反例。启动一个新流程来做一些可以在单个 P/Invoke 中完成的事情(不需要重写)是使用大锤来破解。【参考方案9】:

您可以使用 WebClient 类使用凭据连接到网络驱动程序。包括以下命名空间:

using System.Net;

WebClient request = new WebClient();
request.Credentials = new NetworkCredential("domain\username", "password");
string[] theFolders = Directory.GetDirectories(@"\\computer\share");

【讨论】:

Directory.GetDirectories 与 WebClient 无关 - 它们恰好是您示例中的相邻代码行

以上是关于使用用户名和密码连接到网络驱动器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用映射的网络驱动器通过数据源 (ODBC) 连接到 Access 数据库?

如何强制 Windows 重新连接到网络驱动器

FTP如何远程登录啊?

ODBC 从 R 连接到网络驱动器上的 Access DB .accdb 文件

ORA-01017: 使用 ODP.NET 托管驱动程序连接到 9i oracle 数据库时用户名/密码无效

ubuntu网络打印机的问题