c# - Azure Function 函数如何使用托管标识获取对 Azure 表存储的引用?

标签 c# azure azure-functions azure-storage azure-managed-identity

我有一个已分配系统标识的 Azure 函数:

System Assigned Identity

我希望 Azure Function 访问存储帐户。该函数在该存储帐户上具有读取者和数据访问角色:

RBAC permissions

该函数已配置了要使用的存储帐户的名称。然后该函数尝试获取 CloudTableClient 的实例:

public async Task InitAsync(string accountsStorageName)
{
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync(accountsStorageName);
    
    var storageCredential = new StorageCredentials(accessToken);
    var storageAccount = new CloudStorageAccount(storageCredential, accountsStorageName, "core.windows.net", true);
                
     //  Gets the client to the account's Table storage.
    m_tableClient = storageAccount.CreateCloudTableClient();
}

问题

上面的代码失败,因为它无法获取访问 token :

Error

Azure 函数如何使用托管标识获取对 Azure 表存储的引用?

最佳答案

Azure Key Vault 可以生成共享访问签名 token 。共享访问签名提供对存储帐户中资源的委派访问权限。您可以授予客户端对存储帐户中资源的访问权限,而无需共享您的帐户 key 。更多详情请引用here

  1. 设置帐户共享访问签名定义
$storageAccountName = ""
$keyVaultName = ""
$storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -Protocol Https -StorageAccountKey Key1
$start = [System.DateTime]::Now.AddDays(-1)
$end = [System.DateTime]::Now.AddMonths(1)

$sasToken = New-AzStorageAccountSasToken -Service blob,file,Table,Queue -ResourceType Service,Container,Object -Permission "racwdlup" -Protocol HttpsOnly -StartTime $start -ExpiryTime $end -Context $storageContext


Set-AzKeyVaultManagedStorageSasDefinition -AccountName $storageAccountName -VaultName $keyVaultName -Name "<YourSASDefinitionName>" -TemplateUri $sasToken -SasType 'account' -ValidityPeriod ([System.Timespan]::FromDays(30))

enter image description here

  • 配置 Azure Function 的访问策略
  • Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId "Azure Function MSI object id" -PermissionsToSecrets get,list
    
  • 代码
  •   public static class Http
        {
            [FunctionName("Http")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
                ILogger log, ExecutionContext context)
            {
                var azureServiceTokenProvider = new AzureServiceTokenProvider();
                var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
    
                SecretBundle sasToken =await kv.GetSecretAsync(secretIdentifier: "https://testkey02.vault.azure.net:443/secrets/teststorage08-sasToken");
                var storageCredential = new StorageCredentials(sasToken.Value);
                var accountsStorageName = "teststorage08";
                var storageAccount = new CloudStorageAccount(storageCredential, accountsStorageName, "core.windows.net", true);
    
                var tableClient = storageAccount.CreateCloudTableClient();
                var table =tableClient.GetTableReference("Customer");
                await table.CreateIfNotExistsAsync();
                CustomerEntity customer = new CustomerEntity("Harp", "Walter")
                {
                    Email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f7a0969b839285b794989983988498d994989a" rel="noreferrer noopener nofollow">[email protected]</a>",
                    PhoneNumber = "425-555-0101"
                };
    
                TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(customer);
                TableResult result = await table.ExecuteAsync(insertOrMergeOperation);
                CustomerEntity insertedCustomer = result.Result as CustomerEntity;
    
                return new OkObjectResult(insertedCustomer);
    
            }       
        }
    
        public class CustomerEntity : TableEntity
        {
            public CustomerEntity()
            {
            }
    
            public CustomerEntity(string lastName, string firstName)
            {
                PartitionKey = lastName;
                RowKey = firstName;
            }
    
            public string Email { get; set; }
    
            public string PhoneNumber { get; set; }
        }
    

    enter image description here

    关于c# - Azure Function 函数如何使用托管标识获取对 Azure 表存储的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64728574/

    相关文章:

    c# - 分组连续日期

    azure - 将 Azure block blob 复制到 Azure 文件共享?

    c# - Azure 耐用功能错误 "No activity functions are currently registered!"

    c# - 如何在中继器的按钮单击事件处理程序中获取绑定(bind)对象?

    c# - 一组整数作为自己的数据类型

    c# - 使用参数从 JavaScript 调用 C# 方法

    node.js - 如何更新 Node.js 中的代理消息输出属性?

    c# - 依赖注入(inject)无法解析在 Azure 中运行的 .NET Core Function App 中的类型服务

    ios - PasswordSignInAsync 在本地工作但不在 Azure 中工作

    azure - 如何判断 Azure 队列中的最后一条消息何时被删除