使用 RBAC 在 Azure Cosmos DB 帐户中创建数据库

Create database inside Azure Cosmos DB account with RBAC

我为 azure cosmos db 使用 java 版本 4 SDK。我想使用服务主体而不是主密钥在 azure cosmos db 帐户中创建数据库。

我分配给服务主体 DocumentDB Account ContributorCosmos DB Operator 内置角色定义,根据此文档:

https://docs.microsoft.com/pl-pl/azure/role-based-access-control/built-in-roles#cosmos-db-operator

我无法创建 CosmosAsyncClient,直到我添加了新的自定义角色,它只包含读取元数据。上面提到的内置角色定义不包含它...

 TokenCredential ServicePrincipal = new ClientSecretCredentialBuilder()
            .authorityHost("https://login.microsoftonline.com")
            .tenantId(tenant_here)
            .clientId(clientid_here)
            .clientSecret(secret_from_above_client)
            .build();

 client = new CosmosClientBuilder()
                            .endpoint(AccountSettings.HOST)
                            .credential(ServicePrincipal)
                            .buildAsyncClient();

添加此角色后,客户端已创建,但下一步我无法创建数据库实例以及其中的容器。在访问控制中,我可以看到分配了角色,因此这里的服务主体是正确的。

此外,当我首先使用主密钥创建数据库和容器然后我想使用服务主体 read/write 数据时,它起作用了(显然在添加自定义角色之后也用于写入)。

那我不知道为什么DocumentDB Account ContributorCosmos DB Operator对创建数据库不起作用。

看起来这是 java SDK 中的一个错误,DocumentDB Account Contributor 角色足以创建数据库和容器,因为它具有 Microsoft.DocumentDb/databaseAccounts/* 权限(* 是一个通配符,它​​还包括你提到的Microsoft.DocumentDB/databaseAccounts/readMetadata)。

当我测试使用具有此角色的服务主体通过 powershell 创建数据库时 New-AzCosmosDBSqlDatabase, it works fine. When using the service principal to run this command, it essentially uses the Azure AD client credential flow to get the token, then uses the token to call the REST API - PUT https://management.azure.com/subscriptions/xxxx/resourceGroups/xxxx/providers/Microsoft.DocumentDB/databaseAccounts/xxxx/sqlDatabases/testdb1?api-version=2020-04-01 to create the database, the java SDK 本质上也是做同样的事情,所以它也应该有效。