如何通过X509证书认证的IoT Hub设备下载Azure Blob存储文件?
使用X509证书认证的IoT设备下载Azure Blob存储文件的解决方案
核心思路
Azure IoT Hub的DeviceClient未提供直接获取Blob下载SAS URI的API,我们可以让设备借助自身的X509证书向Azure AD请求访问令牌,通过令牌授权访问Blob存储,实现文件下载。
前置配置
- 在Azure AD中注册服务主体(应用程序),将设备使用的X509证书公钥绑定到该主体(确保证书指纹匹配)。
- 为该服务主体分配Storage Blob Data Reader角色到目标Blob存储容器或账户,授予下载权限。
设备端实现步骤
1. 获取Azure AD访问令牌
使用设备的X509证书向Azure AD请求Blob存储的访问令牌:
using System.Security.Cryptography.X509Certificates; using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; public async Task<string> GetAzureAdTokenAsync(X509Certificate2 certificate, string tenantId, string clientId) { var tokenEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token"; using var httpClient = new HttpClient(); var requestContent = new FormUrlEncodedContent(new Dictionary<string, string> { {"grant_type", "client_credentials"}, {"client_id", clientId}, {"scope", "https://storage.azure.com/.default"} }); httpClient.DefaultRequestHeaders.Add("X-Client-Cert", Convert.ToBase64String(certificate.Export(X509ContentType.Cert))); using var requestMessage = new HttpRequestMessage(HttpMethod.Post, tokenEndpoint) { Content = requestContent }; requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); var response = await httpClient.SendAsync(requestMessage); response.EnsureSuccessStatusCode(); var responseJson = await response.Content.ReadAsStringAsync(); var tokenData = JsonSerializer.Deserialize<JsonElement>(responseJson); return tokenData.GetProperty("access_token").GetString(); }
2. 使用令牌下载Blob
拿到令牌后,创建BlobClient并执行下载操作:
using Azure.Storage.Blobs; using Azure.Core; public async Task DownloadBlobAsync(string accessToken, string storageAccountName, string containerName, string blobName, string localFilePath) { var tokenCredential = new TokenCredential(accessToken); var blobServiceClient = new BlobServiceClient(new Uri($"https://{storageAccountName}.blob.core.windows.net"), tokenCredential); var blobClient = blobServiceClient.GetBlobContainerClient(containerName).GetBlobClient(blobName); await blobClient.DownloadToAsync(localFilePath); }
3. 整合流程
结合现有设备认证代码,完成完整下载流程:
// 现有X509设备认证逻辑 var deviceId = "你的设备ID"; var x509Certificate = new X509Certificate2("设备证书路径.pfx", "证书密码"); var _auth = new DeviceAuthenticationWithX509Certificate(deviceId, x509Certificate); // 获取AD令牌 var tenantId = "你的Azure AD租户ID"; var clientId = "AD服务主体客户端ID"; var accessToken = await GetAzureAdTokenAsync(x509Certificate, tenantId, clientId); // 执行下载 var storageAccountName = "你的存储账户名"; var containerName = "目标容器名"; var blobName = "Blob文件路径/文件名.txt"; var localSavePath = "本地保存路径/文件名.txt"; await DownloadBlobAsync(accessToken, storageAccountName, containerName, blobName, localSavePath);
替代方案(轻量Serverless后端)
若不想配置Azure AD,可搭建极简Azure Function:
- 创建HTTP触发的Function,接收设备通过IoT Hub直接方法传递的Blob名称请求
- Function通过Key Vault获取存储账户连接字符串,生成下载SAS URI并返回给设备
- 设备拿到SAS URI后直接下载Blob
内容的提问来源于stack exchange,提问作者Dominik Teroerde
相关产品推荐
相关产品推荐

