【问题标题】:Accessing the file share from Azure Worker Role从 Azure 辅助角色访问文件共享
【发布时间】:2013-04-15 11:51:21
【问题描述】:

我们希望在 Windows Azure 中迁移我们的 FTP 服务器。我们创建了干净的虚拟机映像并在那里安装了 FTP 服务器。现在,为了能够直接从 Windows Azure 数据中心处理驻留在 FTP 目录中的文件,我们创建了文件共享和端点(端口 445 TCP 和 UDP)。如果我们尝试从 Worker Role 访问 FTP 服务器的文件共享,我们通常会得到'对路径'...'的访问被拒绝。'。我们可以从 Worker Role 通过远程桌面访问 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

【问题讨论】:

    标签: azure azure-worker-roles file-sharing


    【解决方案1】:

    是的,好像是用户的问题,主机下的进程正在运行。要解决此问题,您可以创建具有管理员权限的新用户(例如在启动任务的帮助下,在角色启动时)并模拟执行的代码。你可以看到示例实现here

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

    【讨论】:

      【解决方案2】:

      我认为这是一个安全问题:用户(工作角色在其下运行)无法在网络共享上进行身份验证。在 Directory.GetFiles 之前尝试“网络使用”

      来自 C# 的“网络使用”:Access a Remote Directory from C#

      【讨论】:

      • 不,如果我将共享映射为驱动器,我会得到异常 System.IO.DirectoryNotFoundException: 找不到路径的一部分 'Z:\'
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 2015-12-22
      • 1970-01-01
      • 2012-06-11
      • 2012-11-29
      • 2014-12-24
      相关资源
      最近更新 更多