user1147862
user1147862

Reputation: 4226

UnauthorizedAccessException using Azure Files when storage account network access enabled for selected networks only

My website (ASP.NET Core, Windows, hosted in Azure app service using IIS) uses the Azure Files feature of my Azure Storage Account to read and write files and directories. It does this using the normal System.IO methods File.Open, etc.

This all works fine as long "Public network access" on the Networking page of the storage account is set to "Enabled from all networks".

However, I have now locked this down using a virtual network, so only my app service can talk to the storage account. Also created a managed identity for the app service and gave that identity the RBAC roles

on the storage account.

As soon as I set "Public network access" on the Networking page of the storage account to "Enabled from selected virtual networks and IP addresses", attempts to write a file now lead to an exception

UnauthorizedAccessException: Access to the path '\\mystorage.file.core.windows.net\mydirectory\mfile.txt' is denied.

However, writing to a blob works fine. So the app service does reach the storage account.

What do I need to do to access my files with the storage account only accessible from the app service? I would much prefer to continue using the System.IO methods so I don't have to modify the application.

Upvotes: 0

Views: 143

Answers (2)

Venkat V
Venkat V

Reputation: 7820

UnauthorizedAccessException using Azure Files when storage account network access enabled for selected networks only

The error you encountered is due to a permission issue. If you can access the blob from an app service, there is no issue with the network configuration.

If you are trying to access the File Share data from the app service using the RBAC method, please configure the authentication method for the Microsoft Entra user account in Azure File Share.

enter image description here

If you are using the App Service system-managed identity to access the Azure File Share, make sure to assign the Storage File Data Privileged Contributor role to the app identity. For more details, follow this link.

Ensure that you use the identity-based authentication method in your code, rather than a SAS token or access keys.

In my case, I enabled identity for the App Service and mounted the Azure File Share on the App Service.

enter image description here

After enabling the identity and logging in with the App Service identity, try accessing the Azure File Share data, as it should work as expected.

enter image description here

Storage account firewall setting

enter image description here

App service network setting

enter image description here

Upvotes: 0

ewencodes
ewencodes

Reputation: 1

To enable private access, you need to use Azure Private Endpoint.

In your case, you need to create one private endpoint per sub-resource and so one for blob access and another one for file share access.

If you use Terraform :

resource "azurerm_private_endpoint" "blob" {
  name                = "pe-stxxxx-blob"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  subnet_id           = azurerm_subnet.example.id

  private_service_connection {
    name                           = "example-privateserviceconnection"
    private_connection_resource_id = azurerm_storage_account.example.id
    subresource_names              = ["blob"] <------
    is_manual_connection           = false
  }

  private_dns_zone_group {
    name                 = "example-dns-zone-group"
    private_dns_zone_ids = [azurerm_private_dns_zone.example.id]
  }
}

resource "azurerm_private_endpoint" "file" {
  name                = "pe-stxxxx-file"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  subnet_id           = azurerm_subnet.example.id

  private_service_connection {
    name                           = "example-privateserviceconnection"
    private_connection_resource_id = azurerm_storage_account.example.id
    subresource_names              = ["file"] <------
    is_manual_connection           = false
  }

  private_dns_zone_group {
    name                 = "example-dns-zone-group"
    private_dns_zone_ids = [azurerm_private_dns_zone.example.id]
  }
}

References :

Upvotes: 0

Related Questions