【Azure Storage Account】利用App Service作为反向代理, 并使用.NET Storage Account SDK实现上传/下载操作

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
注册配置 MSE Nacos/ZooKeeper,182元/月
云原生网关 MSE Higress,422元/月
简介: 本文介绍了如何在Azure上使用App Service作为反向代理,以自定义域名访问Storage Account。主要内容包括:1. **设置反向代理**:通过配置`applicationhost.xdt`和`web.config`文件,启用IIS代理功能并设置重写规则。2. **验证访问**:测试原生URL和自定义域名的访问效果,确保两者均可正常访问Storage Account。3. **.NET SDK连接**:使用共享访问签名(SAS URL)初始化BlobServiceClient对象,实现通过自定义域名访问存储服务。

问题描述

在使用Azure上的存储服务 Storage Account 的时候,有时需要代替 它原本提供的域名进行访问,比如默认的域名为:mystorageaccount.blob.core.chinacloudapi.cn, 想转变为 myservice.file.com

如果使用App Service作为反向代理,我们现在有如下三个疑问:

第一:如何来设置方向代理呢?

第二:是否还能成功访问Storage Account服务呢?

第三:.NET Storage Account SDK中如何使用自定义的域名连接服务呢?

 

问题解答

根据问题中的三个疑问,我们一一测试及解答。

第一问,在App Service服务中如何实现反向代理呢?

参考之前的文章:

  1. 【Azure 应用服务】在App Service for Windows中实现反向代理 : https://www.cnblogs.com/lulight/p/17120713.html
  2. 【应用服务 App Service】 App Service Rewrite 实例 - 反向代理转发功能 : https://www.cnblogs.com/lulight/p/13875393.html

第一步:applicationhost.xdt 启用IIS代理功能

选择一个 Windows 平台的App Service,进入Kudu站点,在 Site 目录下创建 applicationhost.xdt 文件并复制下面的内容

<?xml version="1.0"?>
    <configuration xmlns:xdt=http://schemas.microsoft.com/XML-Document-Transform>
    <system.webServer>
        <proxy xdt:Transform="InsertIfMissing" enabled="true" preserveHostHeader="false" reverseRewriteHostInResponseHeaders="false" />
    </system.webServer>
</configuration>
  • xdt:Transform="InsertIfMissing" 表示如果代理配置不存在,则插入这一配置。
  • enabled="true" 表示启用代理功能。
  • preserveHostHeader="false" 表示不保留原始请求的主机头信息。
  • reverseRewriteHostInResponseHeaders="false" 表示在响应头中不反向重写主机头信息。

第二步:web.config 配置 rewrite rule

第一步完成后,点击 WWWROOT 目录,添加新文件 web.config 并复制下面的内容

<configuration>  
    <system.webServer>  
        <rewrite>  
            <rules>  
                <rule name="root" stopProcessing="true">  
                    <match url="^/?(.*)" />  
                    <action type="Rewrite" url="https://<stroage account name>.blob.core.chinacloudapi.cn/{R:1}" />  
                </rule>  
                
                <!-- 需要对根目录的请求进行反向代理,否则对POST/PUT等操作会报错404无法找到Blob Containers -->
                <!-- <rule name="sa" stopProcessing="true">   -->
                    <!-- <match url="^sa/?(.*)" />   -->
                    <!-- <action type="Rewrite" url="https://<storage account name>.blob.core.chinacloudapi.cn/{R:1}" />   -->
                <!-- </rule>   -->
            </rules>  
        </rewrite>  
    </system.webServer>  
</configuration>

第二问,是否还能成功访问Storage Account服务呢?

完成App Service的反向代理配置后,重启服务。然后进入Storage Account的共享访问签名生成页面。

 

第一步:使用原生的 SAS URL访问Blob文件

原生的URL为:

https://< your storage account >.blob.core.chinacloudapi.cn/<your container name>/<filename>.txt?

sp=r&st=2025-03-01T13:16:47Z&se=2025-03-01T21:16:47Z&spr=https&sv=2022-11-02&sr=b&sig=xxxx%xxxx%3D

第二步:用App Service的域名替换原生的Storage Account域名访问

替换后的URL为:

https://<your app service custom domain name>.chinacloudsites.cn/<your container name>/<filename>.txt?

sp=r&st=2025-03-01T13:16:47Z&se=2025-03-01T21:16:47Z&spr=https&sv=2022-11-02&sr=b&sig=xxxx%xxxx%3D

测试验证,两种域名均可访问。证明,反向代理配置成功!

 

 

第三问:.NET Storage Account SDK中如何使用自定义的域名连接服务呢?

是的,在默认的.NET Storage Account SDK中,默认使用的是连接字符串(Connection String)。

DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=<account-key>;EndpointSuffix=core.chinacloudapi.cn

以上的格式,无法修改EndpointSuffix为自定义的域名。所以,使用连接字符串肯定是不可以的。

代替的方案就是使用共享访问签名(SAS URL)来初始化BlobServiceClient对象。

参考“快速入门:适用于 .NET 的 Azure Blob 存储客户端库” 文章中的代码,只需要修改初始化 Blob Service Client对象的那一段代码就可以,改动量非常小。

//Use SAS URL        
string accountsas = "https://<the app gateway domain name>/?sv=2022-11-02&ss=bfqt&srt=sco&sp=rwdlacupitfx&se=2025-02-28T13:55:27Z&st=2025-02-28T05:55:27Z&spr=https&sig=PxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxD";
Uri sasuri = new Uri(accountsas);
// Create a BlobServiceClient object which will be used to create a container client
BlobServiceClient blobServiceClient = new BlobServiceClient(sasuri);

注意:代码中使用的共享访问签名SAS URL是Storage Account级别的,不能使用第二问中的一个blob文件的SAS URL,否则会出现权限不够报错。

运行效果展示:

 

参考资料

  1. 在App Service for Windows中实现反向代理 : https://www.cnblogs.com/lulight/p/17120713.html
  2. App Service Rewrite 实例 - 反向代理转发功能 : https://www.cnblogs.com/lulight/p/13875393.html
  3. BlobServiceClient 构造函数 : https://learn.microsoft.com/zh-cn/dotnet/api/azure.storage.blobs.blobserviceclient.-ctor?view=azure-dotnet#azure-storage-blobs-blobserviceclient-ctor(system-uri-azure-storage-storagesharedkeycredential-azure-storage-blobs-blobclientoptions)
  4. 快速入门:适用于 .NET 的 Azure Blob 存储客户端库 : https://docs.azure.cn/zh-cn/storage/blobs/storage-quickstart-blobs-dotnet?tabs=visual-studio%2Cconnection-string%2Croles-azure-portal%2Csign-in-azure-cli%2Cidentity-visual-studio

 

附录:如果在设置反向代理的时候,没有从根目录跳转,就会遇见如下错误:

The specified container does not exist.

RequestId:000000

Time:2025-02-28T05:57:16.7457335Z

Status: 404 (The specified container does not exist.)

ErrorCode: ContainerNotFound

Content:

<?xml version="1.0" encoding="utf-8"?><Error><Code>ContainerNotFound</Code><Message>The specified container does not exist. RequestId:00000 Time:2025-02-28T05:57:16.7457335Z</Message></Error>

Headers:

Date: Fri, 28 Feb 2025 05:57:16 GMT

Server: Windows-Azure-Blob/1.0,Microsoft-HTTPAPI/2.0

Set-Cookie: REDACTED

x-ms-request-id: e000000

x-ms-client-request-id: 5e

x-ms-version: 2020-08-04

x-ms-error-code: ContainerNotFound

X-Powered-By: REDACTED

Content-Length: 225

Content-Type: application/xml

附录:完整代码参考


using Azure;
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace BlobQuickstartV12
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine("Azure Blob storage v12 - .NET quickstart sample\n");
            // Retrieve the connection string for use with the application. The storage
            // connection string is stored in an environment variable on the machine
            // running the application called AZURE_STORAGE_CONNECTION_STRING. If the
            // environment variable is created after the application is launched in a
            // console or with Visual Studio, the shell or application needs to be closed
            // and reloaded to take the environment variable into account.
            
            //string connectionString = "Connection String";
 
            string accountsas = " SAS URL ";
 
            Uri sasuri = new Uri(accountsas);
            // Create a BlobServiceClient object which will be used to create a container client
            BlobServiceClient blobServiceClient = new BlobServiceClient(sasuri);
            //Create a unique name for the container
            string containerName = "lbllmpackage";// "quickstartblobs" + Guid.NewGuid().ToString();
            // Create the container and return a container client object
            BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
            Console.WriteLine("Listing blobs...");
            // List all blobs in the container
            await foreach (BlobItem blobItem in containerClient.GetBlobsAsync())
            {
                try
                {
                    Console.WriteLine("\t" + blobItem.Name);
                    BlobClient bclient = containerClient.GetBlobClient(blobItem.Name);
                    await bclient.CreateSnapshotAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
 
            var prp = containerClient.GetProperties();
            // Create a local file in the ./data/ directory for uploading and downloading
            string localPath = @".\data\";
            string fileName = "quickstart" + Guid.NewGuid().ToString() + ".txt";
            string localFilePath = Path.Combine(localPath, fileName);
            // Write text to the file
            await File.WriteAllTextAsync(localFilePath, "Hello, World! the message from .net");
            // Get a reference to a blob
            BlobClient blobClient = containerClient.GetBlobClient("/test/" + fileName);
            Console.WriteLine("Uploading to Blob storage as blob:\n\t {0}\n", blobClient.Uri);
            // Open the file and upload its data
            using FileStream uploadFileStream = File.OpenRead(localFilePath);
            await blobClient.UploadAsync(uploadFileStream, true);
            uploadFileStream.Close();
            Console.WriteLine("Listing blobs...");
            // List all blobs in the container
            await foreach (BlobItem blobItem in containerClient.GetBlobsAsync())
            {
                Console.WriteLine("\t" + blobItem.Name);
            }
            // Download the blob to a local file
            // Append the string "DOWNLOADED" before the .txt extension 
            // so you can compare the files in the data directory
            string downloadFilePath = localFilePath.Replace(".txt", "DOWNLOADED.txt");
            Console.WriteLine("\nDownloading blob to\n\t{0}\n", downloadFilePath);
            // Download the blob's contents and save it to a file
            BlobDownloadInfo download = await blobClient.DownloadAsync();
            using (FileStream downloadFileStream = File.OpenWrite(downloadFilePath))
            {
                await download.Content.CopyToAsync(downloadFileStream);
                downloadFileStream.Close();
            }
        }
    }
}

 

 

[END]



 

当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

相关文章
|
2月前
|
存储 安全 Linux
【Azure App Service】在App Service中查看CA证书
在 Azure App Service 中,使用自签名或私有 CA 证书的远程服务可能会导致 SSL 握手失败。解决方法包括使用受信任 CA 签发的证书,或通过 App Service Environment 加载自定义根证书,实现安全连接。
|
3月前
|
C++ Windows
.NET Framework安装不成功,下载`NET Framework 3.5`文件,Microsoft Visual C++
.NET Framework常见问题及解决方案汇总,涵盖缺失组件、安装失败、错误代码等,提供多种修复方法,包括全能王DLL修复工具、微软官方运行库及命令行安装等,适用于Windows系统,解决应用程序无法运行问题。
215 3
|
3月前
|
域名解析 网络协议 API
【Azure Container App】配置容器应用的缩放规则 Managed Identity 连接中国区 Azure Service Bus 问题
本文介绍了在 Azure Container Apps 中配置基于自定义 Azure Service Bus 的自动缩放规则时,因未指定云环境导致的域名解析错误问题。解决方案是在扩展规则中添加 `cloud=AzureChinaCloud` 参数,以适配中国区 Azure 环境。内容涵盖问题描述、原因分析、解决方法及配置示例,适用于使用 KEDA 实现事件驱动自动缩放的场景。
|
1月前
|
API 网络架构 容器
【Azure Container App】查看当前 Container App Environment 中的 CPU 使用情况的API
在扩展 Azure Container Apps 副本时,因 Container App Environment 的 CPU 核心数已达上限(500 cores),导致扩展失败。本文介绍如何使用 `az rest` 命令调用 Azure China Cloud 管理 API,查询当前环境的 CPU 使用情况,并提供具体操作步骤及示例。
91 16
|
21天前
|
数据安全/隐私保护
【Azure Function App】PowerShell Function 执行 Get-AzAccessToken 的返回值类型问题:System.String 与 System.Security.SecureString
将PowerShell Function部署到Azure Function App后,Get-AzAccessToken返回值类型在不同环境中有差异。正常为SecureString类型,但部分情况下为System.String类型,导致后续处理出错。解决方法是在profile.ps1中设置环境变量$env:AZUREPS_OUTPUT_PLAINTEXT_AZACCESSTOKEN=false,以禁用明文输出。
|
26天前
|
人工智能 编解码 监控
游戏显卡驱动,NVIDIA App ,0xc000007b,amd显卡驱动下载,解决游戏慢,游戏卡等问题
本文介绍了游戏显卡驱动的重要性及安装方法,涵盖NVIDIA和AMD显卡驱动下载与更新,解决游戏卡顿、闪退及报错0xc000007b等问题。提供三款工具推荐,支持自动识别与手动精准安装,优化游戏性能,提升体验。
296 5
|
3月前
|
Java Shell Maven
【Azure Container App】构建Java应用镜像时候遇无法编译错误:ERROR [build 10/10] RUN ./mvnw.cmd dependency:go-offline -B -Dproduction package
在部署Java应用到Azure Container App时,构建镜像过程中出现错误:“./mvnw.cmd: No such file or directory”。尽管项目根目录包含mvnw和mvnw.cmd文件,但依然报错。问题出现在Dockerfile构建阶段执行`./mvnw dependency:go-offline`命令时,系统提示找不到可执行文件。经过排查,确认是mvnw文件内容异常所致。最终通过重新生成mvnw文件解决该问题,镜像成功构建。
|
3月前
|
存储 缓存 Serverless
【Azure Container App】如何在Consumption类型的容器应用环境中缓存Docker镜像
在 Azure 容器应用的 Consumption 模式下,容器每次启动均需重新拉取镜像,导致冷启动延迟。本文分析该机制,并提出优化方案:使用 ACR 区域复制加速镜像拉取、优化镜像体积、设置最小副本数减少冷启动频率,或切换至 Dedicated 模式实现镜像缓存,以提升容器启动效率和应用响应速度。
|
3月前
|
iOS开发 MacOS
如何指定下载不同版本macOS app
本文介绍了多种下载和安装 macOS 的方法,包括使用终端命令下载指定版本的 macOS App 或 PKG 文件,以及通过脚本工具如 installinstallmacos.py 和 fetch-installer-pkg 实现自动化下载。同时还讲解了如何将 macOS 安装程序制作成可启动 U 盘,适用于系统重装或部署场景。
|
16天前
|
移动开发 小程序 Android开发
基于 uni-app 开发的废品回收类多端应用功能与界面说明
本文将对一款基于 uni-app 开发的废品回收类多端应用,从多端支持范围、核心功能模块及部分界面展示进行客观说明,相关资源信息也将一并呈现。
53 0