【问题标题】:Connect Azure CosmosDB using Managed Identities from Azure Function App both locally and on Azure在本地和 Azure 上使用 Azure Function App 中的托管标识连接 Azure CosmosDB
【发布时间】:2022-02-17 23:51:50
【问题描述】:

我按照以下两个部分为函数应用创建托管标识并将其分配给 DocumentDB Account Contributor

https://docs.microsoft.com/en-us/azure/cosmos-db/managed-identity-based-authentication#assign-a-system-assigned-managed-identity-to-a-function-app

https://docs.microsoft.com/en-us/azure/cosmos-db/managed-identity-based-authentication#grant-access-to-your-azure-cosmos-account

Microsoft.Azure.Services.AppAuthentication

当我尝试运行以下部分中的代码时出现异常:

https://docs.microsoft.com/en-us/azure/cosmos-db/managed-identity-based-authentication#programmatically-access-the-azure-cosmos-db-keys

无法加载文件或程序集'System.Text.Encodings.Web, 版本=6.0.0.0,文化=中性,PublicKeyToken=cc7b13ffcd2ddd51'。 该系统找不到指定的文件。 在 System.Text.Json.Serialization.Metadata.JsonPropertyInfo.DeterminePropertyName() 在 System.Text.Json.Serialization.Metadata.JsonPropertyInfo.GetPolicies(Nullable1 ignoreCondition, Nullable1 declaringTypeNumberHandling) 在 ... System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在 Cosmos.Samples.AzureFunctions.AzureFunctionsCosmosClientMI.d__7.MoveNext() 在 C:.ME\MyLab.Code\AzureCode\CosmosDB\azure-cosmos-dotnet-v3-usage\AzureFunctions\AzureFunctionsCosmosClientMI.cs:line 85

Azure.Identity

由于 MS 不推荐AppAuthentication,所以我通过以下链接切换到使用Azure.Identityhttps://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme?view=azure-dotnet

https://joonasaijala.com/2021/07/01/how-to-using-managed-identities-to-access-cosmos-db-data-via-rbac-and-disabling-authentication-via-keys/

以及下面的代码

 static string cosmosUrl = "https://xxx.documents.azure.com:443/";
    private static CosmosClient client = new CosmosClient(cosmosUrl, new DefaultAzureCredential());
   var container = client.GetContainer("FamilyDatabase", "FamilyContainer");
        try
        {
            var result = await container.CreateItemAsync<Item>(data, new PartitionKey(data.LastName));
            return new OkObjectResult(result.Resource.Id);
        }
        catch (CosmosException cosmosException)
        {
            log.LogError("Creating item failed with error {0}", cosmosException.ToString());
            return new BadRequestObjectResult($"Failed to create item. Cosmos Status Code {cosmosException.StatusCode}, Sub Status Code {cosmosException.SubStatusCode}: {cosmosException.Message}.");
        }

但是,我在本地和在 Azure 中运行时都遇到了以下异常。

创建项目失败。 Cosmos 状态码禁止,子状态码 5301:响应状态码不表示成功:Forbidden (403); 子状态:5301;活动编号:xxxx-bf03-4355-8642-5d316f9d3373; 原因:(请求被 Auth xxxx 阻止:请求被阻止,因为 主体 [xxx-2bff-44e9-97be-9ffeb3aae3ee] 没有 执行操作所需的 RBAC 权限 资源 [/] 上的 [Microsoft.DocumentDB/databaseAccounts/readMetadata]。 了解更多:https://aka.ms/cosmos-native-rbac。活动编号: xxx-bf03-4355-8642-5d316f9d3373, Microsoft.Azure.Documents.Common/2.14.0、Windows/10.0.14393 cosmos-netstandard-sdk/3.24.1);.

在本地,我通过链接登录 VS https://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#authenticating-via-visual-studio

有解决 Azure.Identity 问题的想法吗?

参考:

Connect Function App to CosmosDB with Managed Identity

https://github.com/Azure/azure-sdk-for-net/tree/Azure.Identity_1.5.0/sdk/identity/Azure.Identity/samples

【问题讨论】:

    标签: azure azure-functions azure-cosmosdb azure-managed-identity


    【解决方案1】:

    今天早上我在设置 CosmosDB 以使用我的 Azure VM 的托管标识时遇到了同样的错误。错误消息指出您的委托人没有 RBAC 权限 Microsoft.DocumentDB/databaseAccounts/readMetadata。一旦你给了你使用该权限的主体,使用 Azure.Identity 的身份验证应该可以工作。

    DocumentDB Account Contributor 没有角色 Microsoft.DocumentDB/databaseAccounts/readMetadata,我找不到包含该权限的内置 Azure 角色所以我按照article 中的示例创建了自己的自定义 CosmosDBReadWrite 角色。

    要创建自定义角色定义和分配,您需要安装 Azure CLI

    配置自定义角色定义

    准备 JSON 角色定义文件

    首先,您需要创建一个包含角色定义的 json 文件。这里有 2 个不同的自定义角色配置 json 文件,一个用于对 CosmosDB 的只读访问,另一个具有读写角色访问权限。

    只读自定义角色的Json文件
    {
        "RoleName": "CosmosDBReadOnlyRole",
        "Type": "CustomRole",
        "AssignableScopes": ["/"],
        "Permissions": [{
            "DataActions": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
            ]
        }]
    }
    
    读写自定义角色的Json文件
    {
        "RoleName": "CosmosDBReadWriteRole",
        "Type": "CustomRole",
        "AssignableScopes": ["/"],
        "Permissions": [{
            "DataActions": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
            ]
        }]
    }
    

    创建和分配角色定义

    使用自定义角色定义保存 json 文件后,我们可以使用 Azure CLI 创建自定义角色,然后将其分配给正确的主体。

    使用您在上面创建的 JSON 文件创建您的自定义角色

    resourceGroupName='<myResourceGroup>'
    accountName='<myCosmosAccount>'
    az cosmosdb sql role definition create -a $accountName -g $resourceGroupName -b @role-definition.json
    

    创建角色后,应返回创建角色的定义。如果没有,请使用以下命令查找 roleDefinitionId,它可以在 name 属性中找到。

    az cosmosdb sql role definition list --account-name $accountName -g $resourceGroupName
    

    最后,将自定义角色应用于需要访问 CosmosDB 权限的主体。

    resourceGroupName='<myResourceGroup>'
    accountName='<myCosmosAccount>'
    roleDefinitionId = '<roleDefinitionId>'
    principalId = '<ID for the Object that needs access to the CosmosDB>'
    az cosmosdb sql role assignment create -a $accountName -g $resourceGroupName -s "/" -p $principalId -d $roleDefinitionId
    

    希望这也能解决您遇到的错误!

    【讨论】:

      猜你喜欢
      • 2021-08-03
      • 2022-07-14
      • 2022-10-24
      • 2021-01-26
      • 2021-08-15
      • 1970-01-01
      • 2020-05-02
      • 1970-01-01
      • 2019-03-15
      相关资源
      最近更新 更多