I have several storage accounts and successfully configured an Azure point-to-site VPN connection to be able to connect to them. My initial test with Azure Storage Explorer only validated that you could browse the directories/files when connected via Azure VPN (point-to-site using Azure VPN Client), but later I found out that I cannot rename or delete files/directories (not authorized). However, I can upload new files and folders without any issue. Public network access for the storage account is "Enabled from selected virtual networks and IP addresses" and the box to "Allow Azure services on the trusted services list to access this storage account" is also checked (no public IPs are added as exceptions). Select virtual networks are also added. If I add my public IP address as an exception I can rename and delete files/directories. If I choose "Disabled" for public network access, the results are the same - I can still connect via VPN and browse files/directories using Azure Storage Explorer, but when I try to delete or rename a file/directory it fails.
I have private endpoints setup for the storage accounts and I configured a DNS private resolver. DNS correctly resolves to the private IP address when connected via VPN. I setup the Azure VPN clientconfig as follows, and it appears to be working correctly:
<clientconfig>
<dnssuffixes>
<dnssuffix>.azurecr.io</dnssuffix>
<dnssuffix>.azuredatabricks.net</dnssuffix>
<dnssuffix>.azurestaticapps.net</dnssuffix>
<dnssuffix>.1.azurestaticapps.net</dnssuffix>
<dnssuffix>.2.azurestaticapps.net</dnssuffix>
<dnssuffix>.azurewebsites.net</dnssuffix>
<dnssuffix>.scm.azurewebsites.net</dnssuffix>
<dnssuffix>.blob.core.windows.net</dnssuffix>
<dnssuffix>.privatelink.blob.core.windows.net</dnssuffix>
<dnssuffix>.database.windows.net</dnssuffix>
<dnssuffix>.datafactory.azure.net</dnssuffix>
<dnssuffix>.dfs.core.windows.net</dnssuffix>
<dnssuffix>.file.core.windows.net</dnssuffix>
<dnssuffix>.postgres.database.azure.com</dnssuffix>
<dnssuffix>.vault.azure.net</dnssuffix>
<dnssuffix>.vaultcore.azure.net</dnssuffix>
<dnssuffix>.wvd.microsoft.com</dnssuffix>
<dnssuffix>.azurecontainerapps.io</dnssuffix>
</dnssuffixes>
<dnsservers>
<dnsserver>x.x.x.x</dnsserver>
</dnsservers>
</clientconfig>
In a nutshell, the error I get when I try to rename/delete is:
AuthorizationFailure - This request is not authorized to perform this operation.
I've included some lines from the Azure Storage Explorer error at the end, but the full error is over 6000 lines, most of it not really helpful.
I have the contributor role on the storage accounts, so permission should not be an issue, and if I add my IP address as a firewall exception it works as expected. I also tried adding a connection in Azure Storage Explorer, for a Storage account or service, using a SAS key (full permissions - all boxes checked), and the behavior was the same - I could browse, but not delete or rename. I'm running the newest version of Azure Storage Explorer (1.34.0 (99), AzCopy Version: 10.24.0) as of the posting of this issue.
Can anyone else successfully rename/delete files/directories when connected via VPN? Why isn't this working as expected? What have I missed? Is this a bug?
Thanks!
{
"name": "RestError",
"message": "This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z",
"stack": "RestError: This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z\n at handleErrorResponse (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:15:2973)\n at C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:15:1827\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async ll.attemptSendRequest (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:36:58311)\n at async ml.sendOperationRequest (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:16:12049)\n at async a.move (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:42:12256)\n at async mc.runOperation (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:59:6274)\n at async mc.movePath (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:106:16391)\n at async renamePath (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:106:26156)\n at async Azure.Storage.AdlsGen2.renamePath (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:108:10482)",
"code": "AuthorizationFailure",
"statusCode": 403,
"request": {
"streamResponseStatusCodes": {},
"url": "https://StorageAccountNameHere.dfs.core.windows.net/data/folder1/folder2/download_copy.svg?mode=legacy",
"method": "PUT",
"headers": {
"_headersMap": {
"accept": {
"name": "Accept",
"value": "application/json"
},
"x-ms-version": {
"name": "x-ms-version",
"value": "2023-11-03"
},
"x-ms-rename-source": {
"name": "x-ms-rename-source",
"value": "/data/folder1/folder2/download%20(2).svg"
},
"user-agent": {
"name": "User-Agent",
"value": "Microsoft Azure Storage Explorer/1.34.0 (win32) azsdk-js-storagedatalake/12.16.0 (NODE-VERSION v20.9.0; Windows_NT 10.0.22631)"
},
"x-ms-client-request-id": {
"name": "x-ms-client-request-id",
"value": "xxxxxx-xxxxxx-xxxxxx-xxxxxx"
},
"authorization": {
"name": "authorization",
"value": "Bearer JSON Web Token Redacted"
}
}
},
"withCredentials": false,
"timeout": 0,
"keepAlive": true,
"decompressResponse": false,
"requestId": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
"operationSpec": {
"path": "/{filesystem}/{path}",
"httpMethod": "PUT",
"responses": {
"201": {
"headersMapper": {
"serializedName": "Path_createHeaders",
"type": {
"name": "Composite",
"className": "PathCreateHeaders",
"modelProperties": {
"date": {
"serializedName": "date",
"xmlName": "date",
"type": {
"name": "DateTimeRfc1123"
}
},
"etag": {
"serializedName": "etag",
"xmlName": "etag",
"type": {
"name": "String"
}
},
"lastModified": {
"serializedName": "last-modified",
"xmlName": "last-modified",
"type": {
"name": "DateTimeRfc1123"
}
},
"requestId": {
"constraints": {
"Pattern": {}
},
"serializedName": "x-ms-request-id",
"xmlName": "x-ms-request-id",
"type": {
"name": "String"
}
},
"version": {
"serializedName": "x-ms-version",
"xmlName": "x-ms-version",
"type": {
"name": "String"
}
},
"continuation": {
"serializedName": "x-ms-continuation",
"xmlName": "x-ms-continuation",
"type": {
"name": "String"
}
},
"contentLength": {
"serializedName": "content-length",
"xmlName": "content-length",
"type": {
"name": "Number"
}
},
"isServerEncrypted": {
"serializedName": "x-ms-request-server-encrypted",
"xmlName": "x-ms-request-server-encrypted",
"type": {
"name": "Boolean"
}
},
"encryptionKeySha256": {
"serializedName": "x-ms-encryption-key-sha256",
"xmlName": "x-ms-encryption-key-sha256",
"type": {
"name": "String"
}
},
"errorCode": {
"serializedName": "x-ms-error-code",
"xmlName": "x-ms-error-code",
"type": {
"name": "String"
}
}
}
}
}
},
"default": {
"bodyMapper": {
"serializedName": "StorageError",
"type": {
"name": "Composite",
"className": "StorageError",
"modelProperties": {
"error": {
"serializedName": "error",
"xmlName": "error",
"type": {
"name": "Composite",
"className": "StorageErrorError"
}
},
"code": {
"serializedName": "Code",
"xmlName": "Code",
"type": {
"name": "String"
}
}
}
}
},
"headersMapper": {
"serializedName": "Path_createExceptionHeaders",
"type": {
"name": "Composite",
"className": "PathCreateExceptionHeaders",
"modelProperties": {
"errorCode": {
"serializedName": "x-ms-error-code",
"xmlName": "x-ms-error-code",
"type": {
"name": "String"
}
}
}
}
}
}
},
"queryParameters": [
{
"parameterPath": [
"options",
"continuation"
],
"mapper": {
"serializedName": "continuation",
"xmlName": "continuation",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"timeout"
],
"mapper": {
"constraints": {
"InclusiveMinimum": 0
},
"serializedName": "timeout",
"xmlName": "timeout",
"type": {
"name": "Number"
}
}
},
{
"parameterPath": [
"options",
"resource"
],
"mapper": {
"serializedName": "resource",
"xmlName": "resource",
"type": {
"name": "Enum",
"allowedValues": [
"directory",
"file"
]
}
}
},
{
"parameterPath": [
"options",
"mode"
],
"mapper": {
"serializedName": "mode",
"xmlName": "mode",
"type": {
"name": "Enum",
"allowedValues": [
"legacy",
"posix"
]
}
}
}
],
"urlParameters": [
{
"parameterPath": "url",
"mapper": {
"serializedName": "url",
"required": true,
"xmlName": "url",
"type": {
"name": "String"
}
},
"skipEncoding": true
}
],
"headerParameters": [
{
"parameterPath": "accept",
"mapper": {
"defaultValue": "application/json",
"isConstant": true,
"serializedName": "Accept",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"requestId"
],
"mapper": {
"serializedName": "x-ms-client-request-id",
"xmlName": "x-ms-client-request-id",
"type": {
"name": "String"
}
}
},
{
"parameterPath": "version",
"mapper": {
"defaultValue": "2023-11-03",
"isConstant": true,
"serializedName": "x-ms-version",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"properties"
],
"mapper": {
"serializedName": "x-ms-properties",
"xmlName": "x-ms-properties",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"modifiedAccessConditions",
"ifModifiedSince"
],
"mapper": {
"serializedName": "If-Modified-Since",
"xmlName": "If-Modified-Since",
"type": {
"name": "DateTimeRfc1123"
}
}
},
{
"parameterPath": [
"options",
"modifiedAccessConditions",
"ifUnmodifiedSince"
],
"mapper": {
"serializedName": "If-Unmodified-Since",
"xmlName": "If-Unmodified-Since",
"type": {
"name": "DateTimeRfc1123"
}
}
},
{
"parameterPath": [
"options",
"pathHttpHeaders",
"cacheControl"
],
"mapper": {
"serializedName": "x-ms-cache-control",
"xmlName": "x-ms-cache-control",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"pathHttpHeaders",
"contentEncoding"
],
"mapper": {
"serializedName": "x-ms-content-encoding",
"xmlName": "x-ms-content-encoding",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"pathHttpHeaders",
"contentLanguage"
],
"mapper": {
"serializedName": "x-ms-content-language",
"xmlName": "x-ms-content-language",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"pathHttpHeaders",
"contentDisposition"
],
"mapper": {
"serializedName": "x-ms-content-disposition",
"xmlName": "x-ms-content-disposition",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"pathHttpHeaders",
"contentType"
],
"mapper": {
"serializedName": "x-ms-content-type",
"xmlName": "x-ms-content-type",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"renameSource"
],
"mapper": {
"serializedName": "x-ms-rename-source",
"xmlName": "x-ms-rename-source",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"leaseAccessConditions",
"leaseId"
],
"mapper": {
"serializedName": "x-ms-lease-id",
"xmlName": "x-ms-lease-id",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"sourceLeaseId"
],
"mapper": {
"serializedName": "x-ms-source-lease-id",
"xmlName": "x-ms-source-lease-id",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"permissions"
],
"mapper": {
"serializedName": "x-ms-permissions",
"xmlName": "x-ms-permissions",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"umask"
],
"mapper": {
"serializedName": "x-ms-umask",
"xmlName": "x-ms-umask",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"modifiedAccessConditions",
"ifMatch"
],
"mapper": {
"serializedName": "If-Match",
"xmlName": "If-Match",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"modifiedAccessConditions",
"ifNoneMatch"
],
"mapper": {
"serializedName": "If-None-Match",
"xmlName": "If-None-Match",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"sourceModifiedAccessConditions",
"sourceIfMatch"
],
"mapper": {
"serializedName": "x-ms-source-if-match",
"xmlName": "x-ms-source-if-match",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"sourceModifiedAccessConditions",
"sourceIfNoneMatch"
],
"mapper": {
"serializedName": "x-ms-source-if-none-match",
"xmlName": "x-ms-source-if-none-match",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"sourceModifiedAccessConditions",
"sourceIfModifiedSince"
],
"mapper": {
"serializedName": "x-ms-source-if-modified-since",
"xmlName": "x-ms-source-if-modified-since",
"type": {
"name": "DateTimeRfc1123"
}
}
},
{
"parameterPath": [
"options",
"sourceModifiedAccessConditions",
"sourceIfUnmodifiedSince"
],
"mapper": {
"serializedName": "x-ms-source-if-unmodified-since",
"xmlName": "x-ms-source-if-unmodified-since",
"type": {
"name": "DateTimeRfc1123"
}
}
},
{
"parameterPath": [
"options",
"cpkInfo",
"encryptionKey"
],
"mapper": {
"serializedName": "x-ms-encryption-key",
"xmlName": "x-ms-encryption-key",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"cpkInfo",
"encryptionKeySha256"
],
"mapper": {
"serializedName": "x-ms-encryption-key-sha256",
"xmlName": "x-ms-encryption-key-sha256",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"cpkInfo",
"encryptionAlgorithm"
],
"mapper": {
"serializedName": "x-ms-encryption-algorithm",
"xmlName": "x-ms-encryption-algorithm",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"owner"
],
"mapper": {
"serializedName": "x-ms-owner",
"xmlName": "x-ms-owner",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"group"
],
"mapper": {
"serializedName": "x-ms-group",
"xmlName": "x-ms-group",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"acl"
],
"mapper": {
"serializedName": "x-ms-acl",
"xmlName": "x-ms-acl",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"proposedLeaseId"
],
"mapper": {
"serializedName": "x-ms-proposed-lease-id",
"xmlName": "x-ms-proposed-lease-id",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"leaseDuration"
],
"mapper": {
"serializedName": "x-ms-lease-duration",
"xmlName": "x-ms-lease-duration",
"type": {
"name": "Number"
}
}
},
{
"parameterPath": [
"options",
"expiryOptions"
],
"mapper": {
"serializedName": "x-ms-expiry-option",
"xmlName": "x-ms-expiry-option",
"type": {
"name": "Enum",
"allowedValues": [
"NeverExpire",
"RelativeToCreation",
"RelativeToNow",
"Absolute"
]
}
}
},
{
"parameterPath": [
"options",
"expiresOn"
],
"mapper": {
"serializedName": "x-ms-expiry-time",
"xmlName": "x-ms-expiry-time",
"type": {
"name": "String"
}
}
},
{
"parameterPath": [
"options",
"encryptionContext"
],
"mapper": {
"serializedName": "x-ms-encryption-context",
"xmlName": "x-ms-encryption-context",
"type": {
"name": "String"
}
}
}
],
...
"response": {
"request": {
"streamResponseStatusCodes": {},
"url": "https://StorageAccountNameHere.dfs.core.windows.net/data/folder1/folder2/download_copy.svg?mode=legacy",
"method": "PUT",
"headers": {
"_headersMap": {
"accept": {
"name": "Accept",
"value": "application/json"
},
"x-ms-version": {
"name": "x-ms-version",
"value": "2023-11-03"
},
"x-ms-rename-source": {
"name": "x-ms-rename-source",
"value": "/data/folder1/folder2/download%20(2).svg"
},
"user-agent": {
"name": "User-Agent",
"value": "Microsoft Azure Storage Explorer/1.34.0 (win32) azsdk-js-storagedatalake/12.16.0 (NODE-VERSION v20.9.0; Windows_NT 10.0.22631)"
},
"x-ms-client-request-id": {
"name": "x-ms-client-request-id",
"value": "xxxxxx-xxxxxx-xxxxxx-xxxxxx"
},
"authorization": {
"name": "authorization",
"value": "Bearer JSON Web Token Redacted"
}
}
},
...
"bodyAsText": "{\"error\":{\"code\":\"AuthorizationFailure\",\"message\":\"This request is not authorized to perform this operation.\\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\\nTime:2024-08-09T20:07:56.5476270Z\"}}",
"parsedBody": {
"error": {
"code": "AuthorizationFailure",
"message": "This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z"
}
},
"parsedHeaders": {
"errorCode": "AuthorizationFailure",
"content-length": "194",
"content-type": "application/json;charset=utf-8",
"date": "Fri, 09 Aug 2024 20:07:55 GMT",
"server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0",
"x-ms-client-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
"x-ms-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
"x-ms-version": "2023-11-03"
}
},
"details": {
"errorCode": "AuthorizationFailure",
"content-length": "194",
"content-type": "application/json;charset=utf-8",
"date": "Fri, 09 Aug 2024 20:07:55 GMT",
"server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0",
"x-ms-client-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
"x-ms-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
"x-ms-version": "2023-11-03",
"error": {
"code": "AuthorizationFailure",
"message": "This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z"
}
}
}