UWP应用中如何以编程方式动态获取Azure存储账户密钥?
解决方案
一、动态获取存储账户密钥的实现方式
要动态获取存储账户密钥,需借助Azure资源管理API,前提是你的应用拥有对应存储账户的密钥读取权限,具体步骤如下:
配置Azure AD应用权限
- 在Azure门户注册一个Azure AD应用,为其分配存储账户密钥操作员服务角色(该角色允许读取存储账户密钥),作用范围设置为目标存储账户或其所属资源组。
- 针对UWP应用,配置身份验证设置,添加"公共客户端(移动和桌面)"平台,重定向URI设为
msal{ClientId}://auth(替换{ClientId}为你的AD应用ID)。
在UWP中获取Azure AD访问令牌
使用Microsoft Authentication Library (MSAL) for .NET获取调用资源管理API的令牌,示例代码如下:var clientId = "你的AD应用ClientId"; var authority = "https://login.microsoftonline.com/你的租户ID"; var scopes = new[] { "https://management.azure.com/.default" }; var pca = PublicClientApplicationBuilder.Create(clientId) .WithAuthority(authority) .WithRedirectUri($"msal{clientId}://auth") .Build(); var result = await pca.AcquireTokenInteractive(scopes) .ExecuteAsync(); string accessToken = result.AccessToken;从Blob URL提取存储账户名
已有的Blob URL包含存储账户信息,可通过简单解析提取账户名,示例:var blobUri = new Uri("你的Blob URL"); string accountName = blobUri.Host.Split('.')[0];调用资源管理API获取密钥
用拿到的访问令牌调用Azure资源管理REST API,获取存储账户密钥:var subscriptionId = "你的订阅ID"; var resourceGroupName = "存储账户所属资源组名"; var apiUrl = $"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/listKeys?api-version=2023-01-01"; using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var response = await client.PostAsync(apiUrl, null); response.EnsureSuccessStatusCode(); var keyResult = await response.Content.ReadFromJsonAsync<StorageAccountKeys>(); string accountKey = keyResult.Keys[0].Value; // 取第一个密钥即可对应的模型类定义:
public class StorageAccountKeys { public List<StorageAccountKey> Keys { get; set; } } public class StorageAccountKey { public string Value { get; set; } }生成连接字符串并操作Blob
用获取到的账户名和密钥生成连接字符串,初始化Blob客户端:string connectionString = $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net"; var blobServiceClient = new BlobServiceClient(connectionString); // 后续可通过blobServiceClient执行容器和Blob的上传下载操作
二、更推荐的替代方案:直接用Azure AD认证Blob操作
既然你不想存储账户密钥,完全可以跳过获取密钥的步骤,直接用Azure AD令牌认证Blob服务,彻底规避密钥轮换的问题,更安全高效:
获取Blob服务的访问令牌
调整MSAL的请求范围为Blob服务专属范围:var scopes = new[] { "https://storage.azure.com/.default" }; // 其余令牌获取逻辑与之前一致用令牌初始化Blob客户端
直接通过令牌和Blob服务终结点创建客户端:var blobServiceUri = new Uri($"https://{accountName}.blob.core.windows.net/"); var tokenCredential = new TokenCredential(accessToken); var blobServiceClient = new BlobServiceClient(blobServiceUri, tokenCredential);这样就能直接进行Blob的上传下载操作,全程无需账户密钥,也不用考虑密钥轮换的问题。
内容的提问来源于stack exchange,提问作者Shabaz
相关产品推荐
相关产品推荐

