Мы столкнулись с интересной ситуацией, которая требует разрешения, и мои поиски закончились ничем. Поэтому я обращаюсь к сообществу SO за помощью.
Проблема заключается в следующем: нам необходим программный доступ к общему файлу, который находится не в нашем домене и не находится в доверенном внешнем домене через удаленный общий доступ к файлам / UNC. Естественно, нам нужно предоставить учетные данные для удаленной машины.
Как правило, эту проблему решают одним из двух способов:
- Сопоставьте общий файловый ресурс как диск и укажите учетные данные. Обычно это делается с помощью
NET USE
команды или дублирующих функций Win32NET USE
. - Получите доступ к файлу с UNC-путем, как если бы удаленный компьютер находился в домене, и убедитесь, что учетная запись, под которой запускается программа, дублируется (включая пароль) на удаленном компьютере как локальный пользователь. В основном используется тот факт, что Windows автоматически предоставит учетные данные текущего пользователя, когда пользователь попытается получить доступ к общему файлу.
- Не используйте удаленный обмен файлами. Используйте FTP (или другие средства) для передачи файла, работайте с ним локально, а затем передайте его обратно.
По разным и разным причинам наши архитекторы безопасности / сети отвергли первые два подхода. Второй подход, очевидно, является дырой в безопасности; если удаленный компьютер скомпрометирован, локальный компьютер теперь находится в опасности. Первый подход неудовлетворителен, поскольку вновь смонтированный диск является общим ресурсом, доступным для других программ на локальном компьютере во время доступа программы к файлам. Хотя это вполне возможно сделать временным, это все еще дыра в их мнении.
Они открыты для третьего варианта, но администраторы удаленных сетей настаивают на SFTP, а не на FTPS, а FtpWebRequest поддерживает только FTPS. SFTP является более дружественным к брандмауэру вариантом, и есть несколько библиотек, которые я мог бы использовать для этого подхода, но я бы предпочел уменьшить свои зависимости, если смогу.
Я искал в MSDN управляемый или win32 способ использования удаленного обмена файлами, но мне не удалось найти ничего полезного.
И поэтому я спрашиваю: есть ли другой путь? Я пропустил сверхсекретную функцию win32, которая делает то, что я хочу? Или я должен использовать какой-то вариант 3?
источник
Ответы:
Способ решения вашей проблемы - использовать Win32 API с именем WNetUseConnection .
Используйте эту функцию для подключения к пути UNC с аутентификацией, а НЕ для сопоставления диска .
Это позволит вам подключиться к удаленному компьютеру, даже если он не находится в одном домене, и даже если у него другое имя пользователя и пароль.
После использования WNetUseConnection вы сможете получить доступ к файлу по UNC-пути, как если бы вы находились в том же домене. Лучший способ, вероятно, через административные встроенные акции.
Пример: \\ имя_компьютера \ c $ \ program files \ Folder \ file.txt
Вот пример кода C #, который использует WNetUseConnection.
Обратите внимание, что для NetResource вы должны передать null для lpLocalName и lpProvider. Тип dwType должен быть RESOURCETYPE_DISK. LpRemoteName должно быть \\ ComputerName.
источник
WNetUseConnection
быть закрыты вручную по телефонуWNetCancelConnection2
? Или есть время простоя (или какой-то другой механизм), и мы не должны беспокоиться?Для людей, которые ищут быстрое решение, вы можете использовать
NetworkShareAccesser
написанное мной недавно (на основании этого ответа (большое спасибо!)):Использование:
ВНИМАНИЕ: Пожалуйста , абсолютно уверен, что
Dispose
изNetworkShareAccesser
называется (даже если приложение падает!), В противном случае открытое соединение будет оставаться на Windows. Вы можете увидеть все открытые соединения, открывcmd
подсказку и введяnet use
.Код:
источник
using System.Runtime.InteropServices;
иusing System.ComponentModel;
дляDllImport
иWin32Exception
AFAIK, вам не нужно сопоставлять UNC-путь с буквой диска, чтобы установить учетные данные для сервера. Я регулярно использовал пакетные сценарии, такие как:
Однако любая программа, работающая с той же учетной записью, что и ваша программа, все равно сможет получить доступ ко всему, к чему
username:password
имеет доступ. Возможное решение может заключаться в том, чтобы изолировать вашу программу от собственной учетной записи локального пользователя (доступ UNC является локальным по отношению к вызывающей учетной записиNET USE
).Примечание: использование SMB в разных доменах не совсем удачное использование технологии, IMO. Если безопасность так важна, тот факт, что SMB не поддерживает шифрование, сам по себе немного затрудняет работу.
источник
NET USE
, это может быть приемлемым подходом. Однако вы уверены, что нам нужно использовать локальную учетную запись? РазвеNET USE
вызов не будет локальным для машины, на которой он был вызван? Вы дали мне хороший исследовательский путьВместо WNetUseConnection я бы порекомендовал NetUseAdd . WNetUseConnection - это устаревшая функция, которая была заменена WNetUseConnection2 и WNetUseConnection3, но все эти функции создают сетевое устройство, которое отображается в проводнике Windows. NetUseAdd является эквивалентом вызова net use в командной строке DOS для аутентификации на удаленном компьютере.
Если вы вызываете NetUseAdd, то последующие попытки доступа к каталогу должны быть успешными.
источник
Хотя я сам не знаю, я, конечно, надеюсь, что № 2 неверен ... Я хотел бы думать, что Windows не собирается АВТОМАТИЧЕСКИ выдавать мою регистрационную информацию (меньше всего мой пароль!) На любую машину не говоря уже о том, что не является частью моего доверия.
Независимо от того, вы исследовали архитектуру олицетворения? Ваш код будет выглядеть примерно так:
В этом случае
token
переменная является IntPtr. Чтобы получить значение для этой переменной, вам нужно вызвать неуправляемую функцию Windows API LogonUser. Быстрая поездка на pinvoke.net дает нам следующую подпись:Имя пользователя, домен и пароль должны казаться довольно очевидными. Посмотрите на различные значения, которые можно передать в dwLogonType и dwLogonProvider, чтобы определить, какое из них лучше всего соответствует вашим потребностям.
Этот код не был протестирован, так как у меня здесь нет второго домена, где я мог бы проверить, но это, мы надеемся, должно вывести вас на правильный путь.
источник
Здесь минимальный класс POC со всеми удаленными кортами
Вы можете напрямую использовать
\\server\share\folder
w /WNetUseConnection
, не нужно разбирать его на\\server
части только заранее.источник
Большинство SFTP-серверов также поддерживают SCP, что облегчает поиск библиотек. Вы даже можете просто вызвать существующий клиент из своего кода, например pscp, включенного в PuTTY .
Если тип файла, с которым вы работаете, является чем-то простым, например, текстовым или XML-файлом, вы можете даже пойти так далеко, чтобы написать собственную реализацию клиент-сервер для управления файлом с помощью чего-то вроде .NET Remoting или веб-сервисов.
источник
Я видел вариант 3, реализованный с помощью инструментов JScape довольно простым способом. Вы можете попробовать. Это не бесплатно, но делает свою работу.
источник
я прилагаю мой код vb.net на основе ссылки Брайана
как это использовать
источник
Я посмотрел на MS, чтобы найти ответы. Первое решение предполагает, что учетная запись пользователя, на котором запущен процесс приложения, имеет доступ к общей папке или диску (тот же домен). Убедитесь, что ваш DNS разрешен или попробуйте использовать IP-адрес. Просто сделайте следующее:
Если вы хотите использовать разные домены .NET 2.0 с учетными данными, следуйте этой модели:
источник