如何使用系统分配的 ID 在本地运行 Azure Function?

问题描述 投票:0回答:1

我正在尝试使用系统分配的托管标识来访问 Azure Cosmos DB 数据,如 Microsoft 文档中所述: https://learn.microsoft.com/en-us/azure/cosmos-db/management-identity-based-authentication

我已在 Azure 函数中创建了系统分配的 ID,并将“Cosmos DB 内置数据读取器”角色分配给了 Cosmos DB(基本上授予了该函数的读取权限)。

然后,我按照“(可选)在本地运行函数”部分中的代码尝试在本地运行我的函数。 但是它失败并显示以下消息: Request blocked by Auth <my cosmos account> : Request is blocked because principal [89c3cdb1-438c-4e04-a16d-...........] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource [/]

此消息中返回的主体 Id 与我的 azure 函数的主体 Id 不同。

显然发生这种情况是因为我的本地帐户的主体 ID 与我在 Azure 上的函数中的系统分配的主体 ID 不同。

但是我找不到任何关于如何在本地设置相同的系统分配原则 id 的信息。

有人有想法吗?

.net azure-active-directory azure-functions azure-cosmosdb azure-identity
1个回答
0
投票

我能找到的关闭解决方法是:

要部署到 Azure,请使用系统分配的身份
  • 对于本地运行函数 - 只需向之前未通过身份验证的本地帐户主体 ID 授予相关权限 (89c3cdb1-438c-4e04-a16d-........................)
  • 因此,让 Azure Function 在 Azure 中和本地运行且麻烦最少的完整步骤是:

在 Function 应用程序中打开系统分配的身份并复制主体 Id
  1. 使用如下命令向系统分配的身份授予权限:
az cosmosdb sql role assignment create \ --resource-group $resourceGroupName \ --account-name $cosmosName \ --role-definition-name "Cosmos DB Built-in Data Contributor" \ --principal-id <Principal Id from Step 1> \ --scope $scope
命令取自 Microsoft 文档:
https://learn.microsoft.com/en-us/azure/cosmos-db/management-identity-based-authentication

    使用
  1. DefaultAzureCredential

    在本地运行该函数。像这样的东西:

     var cosmosDbEndpoint = Environment.GetEnvironmentVariable("CosmosDbEndpoint", EnvironmentVariableTarget.Process);
     var cosmosClient = new CosmosClient(accountEndpoint: cosmosDbEndpoint, new DefaultAzureCredential());
    

  2. 复制错误消息中您本地帐户被阻止的主体 ID
  3. Request is blocked because principal [<blocked principal Id>]

    
    

  4. 使用与步骤 2 中相同的命令向您的本地帐户授予权限,只需使用步骤 5 中的主体 ID:
az cosmosdb sql role assignment create \ --resource-group $resourceGroupName \ --account-name $cosmosName \ --role-definition-name "Cosmos DB Built-in Data Contributor" \ --principal-id <Principal Id from Step 5> \ --scope $scope
当然你可以为这些命令设置不同的定义,但原理是一样的。

我要补充的一件事是,由于必须检查所有凭证类型,本地运行 Function 需要永远花费时间。

因此,为了最大限度地减少执行时间,最好排除所有不必要的凭证类型。假设您的帐户在本地通过 Azure cli 凭据进行身份验证,那么您将创建如下凭据:

var cosmosDbEndpoint = Environment.GetEnvironmentVariable("CosmosDbEndpoint", EnvironmentVariableTarget.Process); var localDebugging = Environment.GetEnvironmentVariable("LocalDebugging"); var credentials = localDebugging is null or not "true" ? new DefaultAzureCredential() : // running on Azure new DefaultAzureCredential(new DefaultAzureCredentialOptions() // running locally { ExcludeManagedIdentityCredential = true, // ExcludeAzureCliCredential = true, ExcludeAzureDeveloperCliCredential = true, ExcludeAzurePowerShellCredential = true, ExcludeEnvironmentCredential = true, ExcludeInteractiveBrowserCredential = true, ExcludeSharedTokenCacheCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = true, ExcludeWorkloadIdentityCredential = true, }); services.AddSingleton<CosmosClient>(sp => new CosmosClient(accountEndpoint: cosmosDbEndpoint, credentials));

© www.soinside.com 2019 - 2024. All rights reserved.