Azure Web App System.UnauthorizedAccessException после развертывания в Azure не может получить доступ к общей папке в локальной сети - PullRequest
0 голосов
/ 23 мая 2018

У нас есть гибридная Azure / локальная сеть.Я могу получить доступ к общему диску \ 192.168.74.10 \ Shared \ LIS \ For Upload \ Reports (в локальной сети) с виртуальной машины в сети Azure.Если я вставляю адрес в проводник, он запрашивает имя пользователя и пароль.После этого я могу получить доступ к папке отчета из виртуальной машины.

Когда я запускаю веб-приложение из Visual Studio с компьютера, подключенного к сети VPN, я могу получить доступ к общему диску 192.168.74.10.Компьютер не является частью AD, просто подключен к сети VPN.После развертывания веб-приложения в облаке Azure я получаю исключение System.UnauthorizedAccessException при попытке доступа к папке.

Я скопировал код WrappedImpersonationContext из другого поста.Добавление WrappedImpersonationContext позволяет моему веб-приложению получать доступ к папке с компьютера, подключенного к сети VPN.

Код WrappedImpersonationContext:

 public sealed class WrappedImpersonationContext
{
    public enum LogonType : int
    {
        Interactive = 2,
        Network = 3,
        Batch = 4,
        Service = 5,
        Unlock = 7,
        NetworkClearText = 8,
        NewCredentials = 9
    }

    public enum LogonProvider : int
    {
        Default = 0,  // LOGON32_PROVIDER_DEFAULT
        WinNT35 = 1,
        WinNT40 = 2,  // Use the NTLM logon provider.
        WinNT50 = 3   // Use the negotiate logon provider.
    }

    [DllImport("advapi32.dll", EntryPoint = "LogonUserW", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain,
        String lpszPassword, LogonType dwLogonType, LogonProvider dwLogonProvider, ref IntPtr phToken);

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

    private string _domain, _password, _username;
    private IntPtr _token;
    private WindowsImpersonationContext _context;

    private bool IsInContext
    {
        get { return _context != null; }
    }

    public WrappedImpersonationContext(string domain, string username, string password)
    {
        _domain = String.IsNullOrEmpty(domain) ? "." : domain;
        _username = username;
        _password = password;
    }

    // Changes the Windows identity of this thread. Make sure to always call Leave() at the end.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public void Enter()
    {
        if (IsInContext)
            return;

        _token = IntPtr.Zero;
        bool logonSuccessfull = LogonUser(_username, _domain, _password, LogonType.NewCredentials, LogonProvider.WinNT50, ref _token);
        if (!logonSuccessfull)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        WindowsIdentity identity = new WindowsIdentity(_token);
        _context = identity.Impersonate();

        Debug.WriteLine(WindowsIdentity.GetCurrent().Name);
    }

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public void Leave()
    {
        if (!IsInContext)
            return;

        _context.Undo();

        if (_token != IntPtr.Zero)
        {
            CloseHandle(_token);
        }
        _context = null;
    }
}

Код для загрузки файлов:

public ActionResult UploadDirectoryEncrypted()
    {

        int fileType = 2;

        StorageCredentials creds = new StorageCredentials(
        ConfigurationManager.AppSettings["accountName"],
        ConfigurationManager.AppSettings["accountKey"]);

        CloudStorageAccount storageAccount = new CloudStorageAccount(creds, useHttps: true);

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

        var impersonationContext = new WrappedImpersonationContext(ConfigurationManager.AppSettings["ServerDomain"], ConfigurationManager.AppSettings["ServerUser"],  ConfigurationManager.AppSettings["ServerPassword"]);
        impersonationContext.Enter();

        string sourceDirectory = @"\\192.168.74.10\Shared\LIS\For Upload\Reports\";            

        var folder = new DirectoryInfo(sourceDirectory);
        var files = folder.GetFiles();
        foreach (var fileInfo in files)
        {
            string blobName = fileInfo.Name;
            string blobFilePath = sourceDirectory + blobName;
            double accession_number = Convert.ToDouble(blobName.Substring(0, blobName.Length - 3));

            CloudBlobContainer container = GetContainer(blobClient, Convert.ToInt32(fileType));

            KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(GetToken);

            var rsa = cloudResolver.ResolveKeyAsync(ConfigurationManager.AppSettings["keyId"], CancellationToken.None).GetAwaiter().GetResult();

            BlobEncryptionPolicy policy = new BlobEncryptionPolicy(rsa, null);
            BlobRequestOptions options = new BlobRequestOptions() { EncryptionPolicy = policy };

            CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

            using (var stream = System.IO.File.OpenRead(blobFilePath))
                blob.UploadFromStream(stream, stream.Length, null, options, null);

            System.IO.File.Delete(blobFilePath);
        }
        impersonationContext.Leave();            
        return RedirectToAction("Index", "User");
    }

Я дал полный контроль над Сетевой службой, IUSR и IIS_IUSRS, но все еще получаю следующую ошибку «Отказано в доступе».

Server Error in '/' Application.
Access to the path '\\192.168.74.10\Shared\LIS\For Upload\Reports' is 
denied.

Description: An unhandled exception occurred during the execution of the 
current web request. Please review the stack trace for more information 
about the error and where it originated in the code. 

Exception Details: System.UnauthorizedAccessException: Access to the path 
'\\192.168.74.10\Shared\LIS\For Upload\Reports' is denied. 

ASP.NET is not authorized to access the requested resource. Consider 
granting access rights to the resource to the ASP.NET request identity. 
ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or 
Network Service on IIS 6 and IIS 7, and the configured application pool 
identity on IIS 7.5) that is used if the application is not impersonating. 
If the application is impersonating via <identity impersonate="true"/>, the 
identity will be the anonymous user (typically IUSR_MACHINENAME) or the 
authenticated request user. 

To grant ASP.NET access to a file, right-click the file in File Explorer, 
choose "Properties" and select the Security tab. Click "Add" to add the 
appropriate user or group. Highlight the ASP.NET account, and check the 
boxes for the desired access.

Что я могу сделать, чтобы получить доступ к папке в локальной сети?

1 Ответ

0 голосов
/ 23 мая 2018

Рекомендуется хранить файлы в хранилище Azure вне виртуального пути или каталога, поскольку это может повлиять на / перезапустить сайт в локальной сети (VS).

...