Доступ к общему файловому ресурсу из рабочей роли Azure

Мы хотим перенести наши FTP-серверы в Windows Azure. Мы создали чистый образ виртуальной машины и установили туда FTP-сервер. Теперь, чтобы иметь возможность обрабатывать файлы, находящиеся в каталоге FTP, непосредственно из центра обработки данных Windows Azure, мы создали общий файловый ресурс и конечные точки (порт 445 TCP и UDP). Если мы пытаемся получить доступ к общей папке FTP-сервера из рабочей роли, мы обычно получаем «Доступ к пути '...' запрещен».. Мы можем получить доступ к общей папке FTP-сервера через удаленный рабочий стол из рабочей роли, что означает правильность конфигурации брандмауэра и FTP. Может ли рабочая роль получить доступ к общим файловым ресурсам в центре обработки данных Windows Azure?

Код:

        try
        {
            const string networkShare = @"...";
            Directory.GetFiles(networkShare).ToList().ForEach(file => Trace.TraceInformation(file));

            Thread.Sleep(10000);
            Trace.WriteLine("Working", "Information");
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }

Исключение:

Exception thrown on running: System.UnauthorizedAccessException: Access to the path '...' is denied.

Server stack trace: 
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileSystemEnumerableIterator`1.CommonInit()
   at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
   at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption, Boolean checkHost)
   at System.IO.Directory.InternalGetFiles(String path, String searchPattern, SearchOption searchOption)
   at KALCIK.NET.Plugin.ReadFromShare.ReadFromSharePlugin.Manipulate(String valueToManipulate)
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at KALCIK.NET.Plugin.Contracts.TextManipulationPluginBase.Manipulate(String valueToManipulate)
   at KALCIK.NET.CloudServices.WorkerRole.BusinessLayers.WorkOrderProcessing.ProcessWorkOrder(Tuple`2 workOrder) in c:\Development\Samples\CloudServicesPlugInSample\CloudServices.WorkerRole\BusinessLayers\WorkOrderProcessing.cs:line 56
   at KALCIK.NET.CloudServices.WorkerRole.WorkOrderProcessorService.Run() in c:\Development\Samples\CloudServicesPlugInSample\CloudServices.WorkerRole\WorkOrderProcessorService.cs:line 67; TraceSource 'WaWorkerHost.exe' event

person Anton Kalcik    schedule 15.04.2013    source источник


Ответы (2)


Да, похоже, проблема в пользователе, под хостом запущен процесс. Чтобы решить эту проблему, вы можете создать нового пользователя с правами администратора (например, с помощью задачи запуска, когда роль запускается) и олицетворять выполняемый код. Вы можете увидеть образец реализации здесь < / а>.

public class WorkerRole : RoleEntryPoint
{

    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);
        }
    }

    [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);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    public override void Run()
    {

        // This is a sample worker implementation. Replace with your logic.
        Trace.WriteLine("TestWorkerRole entry point called", "Information");

        while (true)
        {
            try
            {

                SafeTokenHandle safeTokenHandle;
                var returnValue = LogonUser("username", Environment.MachineName, "password", 2, 0, out safeTokenHandle);

                if (returnValue)
                {
                    using (safeTokenHandle)
                    {
                        using (var impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
                        {
                            const string networkSharePath = @"UNCPath";
                            Directory.GetFiles(networkSharePath).ToList().ForEach(file => Trace.TraceInformation(file));
                        }
                    }

                }

                Thread.Sleep(10000);
                Trace.WriteLine("Working", "Information");
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
            }
        }
    }
}
person Anton Kalcik    schedule 16.04.2013

Я думаю, что это проблема безопасности: пользователь (под которым работает рабочая роль) не может пройти аутентификацию в общей сетевой папке. Попробуйте использовать "net use" перед своим Directory.GetFiles

"чистое использование" из C #: Доступ к удаленному каталогу из C #

person Fabrizio Accatino    schedule 16.04.2013
comment
Нет, также, если я сопоставлю общий ресурс как диск, я получаю Exception System.IO.DirectoryNotFoundException: не удалось найти часть пути 'Z: \' - person Anton Kalcik; 16.04.2013