Доступ к пути xxx запрещен
Прочитав тонны подобных постов, я решил придумать этот. Ну, в принципе, эта проблема похожа на многие другие, но почему-то я не могу заставить ее работать.
Вот сценарий, у меня есть балансировка нагрузки на 2 серверах (servA и servB), и мне нужно заставить приложение создавать только на 1 из них. Поэтому я хочу указать путь UNC при сохранении файлов. У меня, очевидно, есть проблема с созданием файлов в каталоге по сети.
Если я запускаю его с Cassini, все хорошо, я могу получить доступ к пути, потому что он зарегистрирован в моей учетной записи. Как только я перенесу приложение на сервер разработки, оно больше не будет работать. Я знаю, что IIS использует пользователя, связанного с пулом приложений, поэтому я проверил эту учетную запись (которая является network_service) и добавил права на запись в эту папку.
Все еще недостаточно. Что вы думаете о "Все"?! Это должно работать!
О, ну, это не так.
Давайте посмотрим код: Directory.CreateDirectory("\\\\my.ip.over.da.net\\c$\\inetpub\\wwwroot\\projfolder\\otherprojfolder\\test");
И это сообщение, которое я получаю, когда пытаюсь создать эту папку.
{"Message":"Access to the path \u0027\\\\\\\\my.ip.over.da.net\\\\c$\\\\inetpub
\\\\wwwroot\\\\projfolder\\\\otherprojfolder\\\\test\u0027 is denied.","StackTrace":"
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at
System.IO.Directory.InternalCreateDirectory(String fullPath, String path,
DirectorySecurity dirSecurity)\r\n at System.IO.Directory.CreateDirectory(String path,
DirectorySecurity directorySecurity)\r\n at
NSC.Ajax.GetData.testgrid()","ExceptionType":"System.UnauthorizedAccessException"}
Он вызывается через AJAX для облегчения тестирования, поэтому ответ форматируется таким образом.
2 ответа
Проблема в том, что у вас не будет доступа к этому местоположению с использованием учетных данных IIS, сервер разработки будет находиться в отдельном домене где-то еще, и доступ к вашему компьютеру, идущему к общему ресурсу c$ admin, не будет работать, изменение разрешений на этом уровне... немного рискованно...
Если вам действительно нужен доступ к файлам на вашем локальном компьютере с вашего dev-сервера, вам лучше создать общий ресурс под названием test
(C:\inetpub\wwwroot\projfolder\otherprojfolder\test
) на вашей машине и установите разрешения для этого для Everyone
читать (если вам нужно создавать файлы и папки, вам понадобится больше, но я бы посоветовал предоставить только минимальный доступ, с которым вы можете обойтись), хотя это довольно небезопасно, но поскольку ваша машина разработки не будет есть какой-либо способ аутентификации учетной записи в другой сети (с вашего компьютера, с которого вы делитесь файлами), с которым вам нечем играть!
Поэтому создайте локальную общую папку, а затем просто укажите свой код \\\\my.ip.over.da.net\\test
,
Обратите внимание, что вам нужно установить разрешения для общего ресурса и для самой папки, если общий ресурс имеет достаточно разрешений, но ACL для папки не согласен, вы все равно получите отказано в разрешениях.
Вы можете выдать себя за другого пользователя при создании каталога
public static void CreateDirectory(string myDirectory)
{
SafeTokenHandle safeTokenHandle;
bool returnValue = LogonUser(@Username, @Domain, @Password, 2, 0, out safeTokenHandle);
if (returnValue == true)
{
WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
System.IO.Directory.CreateDirectory(myDirectory);
}
}
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
}
Более подробная информация здесь: http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx