При подключении к общему сетевому ресурсу, для которого текущий пользователь (в моем случае пользователь службы с включенной сетью) не имеет прав, необходимо указать имя и пароль.
Я знаю, как сделать это с функциями Win32 (из WNet*
семейства mpr.dll
), но хотел бы сделать это с функциональностью .Net (2.0).
Какие варианты доступны?
Может быть, поможет дополнительная информация:
- Вариант использования - это служба Windows, а не приложение Asp.Net.
- Служба работает под учетной записью, которая не имеет прав на общий ресурс.
- Учетная запись пользователя, необходимая для общего ресурса, неизвестна на стороне клиента.
- Клиент и сервер не являются членами одного домена.
Ответы:
Вы можете либо изменить идентификатор потока, либо P / Invoke WNetAddConnection2. Я предпочитаю последнее, поскольку мне иногда нужно поддерживать несколько учетных данных для разных мест. Я обертываю его в IDisposable и вызываю WNetCancelConnection2, чтобы впоследствии удалить кредиты (избегая ошибки нескольких имен пользователей):
источник
Мне так понравился ответ Марка Брэкетта, что я сделал свою собственную быструю реализацию. Вот если кто-то спешит:
источник
throw new Win32Exception(result);
, так как WNetAddConnection2 возвращает коды ошибок win32 (ERROR_XXX
)NetworkCredential
объекте, приложение могло подключиться один раз к сетевому диску. После этого мы получали ERROR_LOGON_FAILURE при каждой попытке, пока приложение не было перезапущено. Затем мы попытались предоставить домен и дляNetworkCredential
объекта, и вдруг это сработало! Я понятия не имею, почему это решило проблему, особенно тот факт, что он работал, чтобы подключиться один раз без домена.Сегодня, 7 лет спустя, я столкнулся с той же проблемой, и я хотел бы поделиться своей версией решения.
Это готово для копирования и вставки :-) Вот оно:
Шаг 1
В вашем коде (когда вам нужно что-то сделать с разрешениями)
Шаг 2
Вспомогательный файл, который делает магию
источник
Я искал много методов, и я сделал это по-своему. Вы должны открыть соединение между двумя машинами с помощью команды NET USE командной строки и после завершения работы очистить соединение с помощью командной строки NET USE «myconnection» / delete.
Вы должны использовать процесс командной строки из кода, например:
Использование простое:
Вот функции:
А также функция ExecuteCommand:
Эти функции работали очень быстро и стабильно для меня.
источник
Решение Luke Quinane выглядит хорошо, но в моем приложении ASP.NET MVC работало только частично. Имея два общих ресурса на одном сервере с разными учетными данными, я мог использовать олицетворение только для первого.
Проблема с WNetAddConnection2 заключается также в том, что он ведет себя по-разному в разных версиях Windows. Вот почему я искал альтернативы и нашел функцию LogonUser . Вот мой код, который также работает в ASP.NET:
Использование:
источник
Для VB.lovers VB.NET эквивалент кода Люка Куинана (спасибо Люк!)
источник
Один из вариантов, который может работать, - использовать
WindowsIdentity.Impersonate
(и изменить принцип потока), чтобы стать желаемым пользователем, вот так . Вернуться к п / я вызываю, хотя, боюсь ...Другой вариант дерзкий (и в равной степени далека от идеала) , может быть , чтобы породить процесс , чтобы сделать работу ...
ProcessStartInfo
принимает.UserName
,.Password
и.Domain
.Наконец - возможно, запустить службу в выделенной учетной записи, которая имеет доступ?(удалено, поскольку вы пояснили, что это не вариант).источник
ОК ... Я могу ответить ..
Отказ от ответственности: у меня только что был 18+ часовой день (снова) .. Я стар и забыл ... Я не могу произнести по буквам ... У меня короткая продолжительность концентрации внимания, поэтому я лучше отвечаю быстро .. :-)
Вопрос:
Можно ли сменить субъект потока на пользователя без учетной записи на локальном компьютере?
Ответ:
Да, вы можете изменить принципала потока, даже если учетные данные, которые вы используете, не определены локально или находятся вне «леса».
Я только столкнулся с этой проблемой при попытке подключиться к серверу SQL с проверкой подлинности NTLM из службы. В этом вызове используются учетные данные, связанные с процессом, а это означает, что для аутентификации вам потребуется либо локальная учетная запись, либо учетная запись домена. Бла, бла ...
Но...
Вызов LogonUser (..) с атрибутом ???? _ NEW_CREDENTIALS вернет маркер безопасности без попытки аутентификации учетных данных. Kewl .. Не нужно определять учетную запись в «лесу». Когда у вас есть токен, вам, возможно, придется вызвать DuplicateToken () с возможностью включить олицетворение, в результате чего будет получен новый токен. Теперь вызовите SetThreadToken (NULL, токен); (Это может быть & token?) .. Вызов ImpersonateLoggedonUser (token); может потребоваться, но я так не думаю. Поищи это..
Делай то, что тебе нужно сделать ..
Вызовите RevertToSelf (), если вы вызвали ImpersonateLoggedonUser (), а затем SetThreadToken (NULL, NULL); (Я думаю ... посмотрите), а затем CloseHandle () на созданные дескрипторы ..
Никаких обещаний, но это сработало для меня ... Это на макушке моей головы (как мои волосы), и я не могу по буквам !!!
источник
Если вы не можете создать локально действующий токен безопасности, похоже, что вы исключили все панели параметров Win32 API и WNetAddConnection *.
Тонны информации на MSDN о WNet - информация PInvoke и пример кода, который подключается к пути UNC здесь:
Ссылка MSDN здесь:
источник
Также портирован на F # для использования с FAKE
источник
Вы должны смотреть на добавление как это:
В ваш web.config.
Больше информации.
источник