Программная аутентификация удаленных папок / файлов на C # в среде Windows, отличной от домена

Мне нужно иметь возможность программной проверки подлинности при попытке чтения и записи файлов на удаленном компьютере в среде без домена.

Когда вы вводите команду в приглашении Windows RUN, которая похожа на \\ targetComputer \ C $ \ targetFolder или \\ targetComputer \ admin $, где targetComputer НЕ находится в домене, вам будет предложено ввести имя пользователя и пароль. После ввода имени пользователя и пароля вы получаете полный доступ к удаленной папке.

Как я могу выполнить эту аутентификацию программно в C #?

мы пытались ..

- Имитация, но, похоже, работает только в доменной среде.

--CMDKEY.exe, но, похоже, он работает только в доменной среде.

Должен быть способ сделать это, но я искал все выше и ниже безуспешно. Может я'я просто ищу не ту вещь? Я'я уверен, что яЯ не первый, у кого возник этот вопрос. Любая помощь будет принята с благодарностью.

Спасибо!

РЕДАКТИРОВАТЬ :

Я думаю, что только что нашел другое сообщение SO, которое отвечает на мой вопрос:Доступ к общему файлу (UNC) из удаленного ненадежного домена с учетными данными

Сейчас я с этим поработаю и посмотрю, куда меня это приведет.

Спасибо!

 dizzy.stackoverflow20 июн. 2013 г., 22:32
Я думаю, что только что нашел другую публикацию SO, которая отвечает на мой вопрос: Доступ к общему файлу (UNC) из удаленного, ненадежного домена с учетными данными, я пока поработаю с этим и посмотрю, куда он меня доставит. Спасибо!

Ответы на вопрос(1)

Решение Вопроса

Олицетворение работает и с сетью Peer / LAN. У меня есть типичная домашняя сеть с некоторыми машинами по умолчанию "Рабочая группа» и некоторые на именованном, если я вспомнил, что делал это при установке.

Вот код, который я использую из своего приложения на сервере IIS для доступа к файлам на моем другом компьютере (без необходимости иметь одного и того же пользователя и пароль на обеих машинах, копировать их откуда-то и изменять для моего использования):

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.ComponentModel;

/// 
/// 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.
/// 
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");
    }
 Ralis21 июл. 2017 г., 13:00
Решил, что мой путь был неверным.
 Wolf522 июн. 2015 г., 16:06
Это'Это просто олицетворение, так что да, его можно использовать локально для доступа к файлам с разными учетными данными. Он не может получить доступ к файлам на другом компьютере, который не был передан в любом случае.
 Ralis21 июл. 2017 г., 11:46
Когда я получаю доступ к общему каталогу удаленного компьютера, появляется ошибкаУстройство не готово
 stephen23 сент. 2014 г., 01:12
Этот код работал и для меня, хотя я решал немного другую проблему. Моей целью было получить доступ к файлу в сетевой папке, которая использовала домен, отличный от моего локального компьютера. Удивительно, несмотря на импорт DLL, он работал прямо из коробки!
 Wolf523 дек. 2016 г., 17:47
мммм. Это не правильный сетевой путь. Откройте общий доступ к папке или диску на сервере, откройте его через проводник, скопируйте путь и используйте его в своей программе. Как \\ server \ myshare или \\ server \ d (ЕСЛИ вы поделили диск d: как "d")
 dizzy.stackoverflow14 нояб. 2014 г., 18:38
Я забыл отчитаться, но просто хотел сказать, что этот код работает отлично. Еще раз спасибо!
 Karthick Rajan22 сент. 2016 г., 12:26
Однажды я получил доступ к файлам, используя приведенный выше код. После того, как я буду удалить доступ к общей папке? , Потому что при доступе к общей папке в Window он будет хранить идентификатор пользователя и пароль в кэше. Так есть ли необходимость удалить этот кэш?
 Wolf508 окт. 2013 г., 09:20
Ключ: LOGON32_LOGON_NEW_CREDENTIALS. Я попробовал все разные варианты, и LOGON32_LOGON_NEW_CREDENTIALS был тем, который работал. Остальная часть кода является общей.
 Pabitra Dash22 июн. 2015 г., 11:16
Можно ли получить доступ к файлу / папке без общего доступа, используя этот метод?
 Yahya Hussein21 дек. 2016 г., 08:56
Можете ли вы указать правильный путь к файлу удаленного компьютера? моя машина называется Server, и мне нужно получить доступ к диску D на ней, при попытке получить сообщение об ошибке: var files = System.IO.Directory.GetFiles ("\\ Server \\ D:»);
 dizzy.stackoverflow08 окт. 2013 г., 21:08
Очень интересно. Я обязательно попробую и доложу. Спасибо!
 Wolf522 сент. 2016 г., 22:57
Я не знаю ни одного механизма кэширования с этим методом. Я бы предположил, что кэширование не происходит. Кэширование происходит, когда вы получаете всплывающее окно в Windows, вводите учетные данные и проверяете "Запомнить учетные данные", Просто протестируйте выполнение кода и проверьте диспетчер учетных данных, чтобы увидеть, были ли добавлены какие-либо новые записи.
 dizzy.stackoverflow07 окт. 2013 г., 00:27
Я смог использовать следующий код для решения моей проблемы:stackoverflow.com/questions/659013/..., Однако я'Мне любопытно протестировать ваш код позже (я думаю, что на самом деле, возможно, у меня возникло ... ощущение, что я видел этот код в SO до того, как опубликовал этот вопрос) и посмотреть, как он сравнивается с моим исходным кодом олицетворения. Первый взгляд на ваш код состоит в том, что он выглядит точно так же, как код, который я использовал ранее, но только в доменных средах. Я буду смотреть на это более подробно позже. Благодарю.

Ваш ответ на вопрос