保护对 Azure Cosmos DB 中数据的访问Secure access to data in Azure Cosmos DB

适用于: SQL API

本文概述了 Azure Cosmos DB 中的数据访问控制。This article provides an overview of data access control in Azure Cosmos DB.

Azure Cosmos DB 提供了三种方法来控制对数据的访问。Azure Cosmos DB provides three ways to control access to your data.

访问控制类型Access control type 特征Characteristics
主键Primary keys 允许任何管理或数据操作的共享机密。Shared secret allowing any management or data operation. 它包括读写变量和只读变量。It comes in both read-write and read-only variants.
基于角色的访问控制(预览)Role-based access control (Preview) 使用 Azure Active Directory (AAD) 标识进行身份验证的细化、基于角色的权限模型。Fine-grained, role-based permission model using Azure Active Directory (AAD) identities for authentication.
资源令牌Resource tokens 基于本机 Azure Cosmos DB 用户和权限的细化权限模型。Fine-grained permission model based on native Azure Cosmos DB users and permissions.

主键Primary keys

主密钥提供对数据库帐户的所有管理资源的访问权限。Primary keys provide access to all the administrative resources for the database account. 每个帐户包括两个主密钥:主要密钥和辅助密钥。Each account consists of two primary keys: a primary key and secondary key. 使用两个密钥的目的是为了能够重新生成或轮换密钥,从而可以持续访问帐户和数据。The purpose of dual keys is to let you regenerate, or roll keys, providing continuous access to your account and data. 若要了解有关主密钥的详细信息,请参阅数据库安全性一文。To learn more about primary keys, see the Database security article.

密钥轮换Key rotation

轮换主密钥的过程相当简单。The process of rotating your primary key is simple.

  1. 导航到 Azure 门户以检索辅助密钥。Navigate to the Azure portal to retrieve your secondary key.

  2. 在应用程序中将主密钥替换为辅助密钥。Replace your primary key with your secondary key in your application. 确保所有部署中的所有 Cosmos DB 客户端都立即重启,并将开始使用已更新的密钥。Make sure that all the Cosmos DB clients across all the deployments are promptly restarted and will start using the updated key.

  3. 在 Azure 门户中轮换主密钥。Rotate the primary key in the Azure portal.

  4. 验证新主密钥是否适用于所有资源。Validate the new primary key works against all resource. 密钥轮换过程所需时间可能短于一分钟,也可能长达数小时,具体取决于 Cosmos DB 帐户的大小。Key rotation process can take anywhere from less than a minute to hours depending on the size of the Cosmos DB account.

  5. 将辅助密钥替换为新的主密钥。Replace the secondary key with the new primary key.

    Azure 门户中的主密钥轮换 - 演示 NoSQL 数据库安全性

有关如何使用主密钥的代码示例Code sample to use a primary key

以下代码示例演示如何使用 Cosmos DB 帐户终结点和主密钥来实例化 DocumentClient 并创建数据库:The following code sample illustrates how to use a Cosmos DB account endpoint and primary key to instantiate a DocumentClient and create a database:

//Read the Azure Cosmos DB endpointUrl and authorization keys from config.
//These values are available from the Azure portal on the Azure Cosmos DB account blade under "Keys".
//Keep these values in a safe and secure location. Together they provide Administrative access to your Azure Cosmos DB account.

private static readonly string endpointUrl = ConfigurationManager.AppSettings["EndPointUrl"];
private static readonly string authorizationKey = ConfigurationManager.AppSettings["AuthorizationKey"];

CosmosClient client = new CosmosClient(endpointUrl, authorizationKey);

以下代码示例演示如何使用 Azure Cosmos DB 帐户终结点和主密钥来实例化 CosmosClient 对象:The following code sample illustrates how to use the Azure Cosmos DB account endpoint and primary key to instantiate a CosmosClient object:

HOST = config.settings["host"]
MASTER_KEY = config.settings["master_key"]

DATABASE_ID = config.settings["database_id"]
CONTAINER_ID = config.settings["container_id"]
PARTITION_KEY = PartitionKey(path="/username")


# User that you want to give access to
USERNAME, USERNAME_2 = "user", "user2"

CONTAINER_ALL_PERMISSION = "CONTAINER_ALL_PERMISSION"
PARTITION_READ_PERMISSION = "PARTITION_READ_PERMISSION"
DOCUMENT_ALL_PERMISSION = "DOCUMENT_ALL_PERMISSION"


def create_user_if_not_exists(db, username):
    try:
        user = db.create_user(body={"id": username})
    except exceptions.CosmosResourceExistsError:
        user = db.get_user_client(username)

    return user


def create_permission_if_not_exists(user, permission_definition):
    try:
        permission = user.create_permission(permission_definition)
    except exceptions.CosmosResourceExistsError:
        permission = user.get_permission(permission_definition["id"])

    return permission


def token_client_upsert(container, username, item_id):
    try:
        container.upsert_item(
            {
                "id": item_id,
                "username": username,
                "msg": "This is a message for " + username,
            }
        )
    except exceptions.CosmosHttpResponseError:
        print("Error in upserting item with id '{0}'.".format(item_id))


def token_client_read_all(container):
    try:
        items = list(container.read_all_items())
        for i in items:
            print(i)
    except exceptions.CosmosResourceNotFoundError:
        print("Cannot read items--container '{0}' not found.".format(container.id))
    except exceptions.CosmosHttpResponseError:
        print("Error in reading items in container '{0}'.".format(container.id))


def token_client_read_item(container, username, item_id):
    try:
        item = container.read_item(item=item_id, partition_key=username)
        print(item)
    except exceptions.CosmosResourceNotFoundError:
        print("Cannot read--item with id '{0}' not found.".format(item_id))
    except exceptions.CosmosHttpResponseError:
        print("Error in reading item with id '{0}'.".format(item_id))


def token_client_delete(container, username, item_id):
    try:
        container.delete_item(item=item_id, partition_key=username)
    except exceptions.CosmosResourceNotFoundError:
        print("Cannot delete--item with id '{0}' not found.".format(item_id))
    except exceptions.CosmosHttpResponseError:
        print("Error in deleting item with id '{0}'.".format(item_id))


def token_client_query(container, username):
    try:
        for item in container.query_items(
            query="SELECT * FROM my_container c WHERE c.username=@username",
            parameters=[{"name": "@username", "value": username}],
            partition_key=username,
        ):
            print(json.dumps(item, indent=True))
    except exceptions.CosmosHttpResponseError:
        print("Error in querying item(s)")


def run_sample():
    client = cosmos_client.CosmosClient(HOST, {"masterKey": MASTER_KEY})

基于角色的访问控制(预览)Role-based access control (Preview)

Azure Cosmos DB 公开了一种内置的基于角色的访问控制 (RBAC) 系统,可让你:Azure Cosmos DB exposes a built-in role-based access control (RBAC) system that lets you:

  • 使用 Azure Active Directory (AAD) 标识来验证数据请求。Authenticate your data requests with an Azure Active Directory (AAD) identity.
  • 使用细粒度的、基于角色的权限模型来授权数据请求。Authorize your data requests with a fine-grained, role-based permission model.

Azure Cosmos DB RBAC 是在以下情况下的理想访问控制方法:Azure Cosmos DB RBAC is the ideal access control method in situations where:

  • 你不希望使用共享机密(如主键),但希望依赖于基于令牌的身份验证机制,You don't want to use a shared secret like the primary key, and prefer to rely on a token-based authentication mechanism,
  • 你希望使用 Azure AD 标识对请求进行身份验证,You want to use Azure AD identities to authenticate your requests,
  • 你需要细化权限模型来严格限制标识允许执行的数据库操作,You need a fine-grained permission model to tightly restrict which database operations your identities are allowed to perform,
  • 你希望将访问控制策略具体化为可分配给多个标识的“角色”。You wish to materialize your access control policies as "roles" that you can assign to multiple identities.

有关 Azure Cosmos DB RBAC 的详细信息,请参阅为 Azure Cosmos DB 帐户配置基于角色的访问控制See Configure role-based access control for your Azure Cosmos DB account to learn more about Azure Cosmos DB RBAC.

资源令牌Resource tokens

资源令牌提供对数据库中应用程序资源的访问权限。Resource tokens provide access to the application resources within a database. 资源令牌:Resource tokens:

  • 提供对特定容器、分区键、文档、附件、存储过程、触发器和 UDF 的访问权限。Provide access to specific containers, partition keys, documents, attachments, stored procedures, triggers, and UDFs.
  • 用户授予对特定资源的权限时创建。Are created when a user is granted permissions to a specific resource.
  • 通过 POST、GET 或 PUT 调用操作权限资源时重新创建。Are recreated when a permission resource is acted upon on by POST, GET, or PUT call.
  • 使用专门针对用户、资源和权限构造的哈希资源令牌。Use a hash resource token specifically constructed for the user, resource, and permission.
  • 生存期受到可自定义的有效期的约束。Are time bound with a customizable validity period. 默认的有效期限为一小时。The default valid time span is one hour. 但是,可将令牌生存期显式指定为最长五个小时。Token lifetime, however, may be explicitly specified, up to a maximum of five hours.
  • 可以安全替代主密钥。Provide a safe alternative to giving out the primary key.
  • 使客户端能够根据它们的权限读取、写入和删除 Cosmos DB 帐户中的资源。Enable clients to read, write, and delete resources in the Cosmos DB account according to the permissions they've been granted.

如果想要为不能通过主密钥得到信任的客户端提供对 Cosmos DB 帐户中资源的访问权限,可以使用资源令牌(通过创建 Cosmos DB 用户和权限来使用)。You can use a resource token (by creating Cosmos DB users and permissions) when you want to provide access to resources in your Cosmos DB account to a client that cannot be trusted with the primary key.

Cosmos DB 资源令牌提供一种安全的替代方案,使客户端能够根据授予的权限读取、写入和删除 Cosmos DB 帐户中的资源,而无需主密钥或只读密钥。Cosmos DB resource tokens provide a safe alternative that enables clients to read, write, and delete resources in your Cosmos DB account according to the permissions you've granted, and without need for either a primary or read only key.

以下是典型的设计模式,通过它可以请求、生成资源令牌并将其提供给客户端:Here is a typical design pattern whereby resource tokens may be requested, generated, and delivered to clients:

  1. 设置中间层服务,以用于移动应用程序共享用户照片。A mid-tier service is set up to serve a mobile application to share user photos.

  2. 中间层服务拥有 Cosmos DB 帐户的主密钥。The mid-tier service possesses the primary key of the Cosmos DB account.

  3. 照片应用安装在最终用户移动设备上。The photo app is installed on end-user mobile devices.

  4. 登录时,照片应用使用中间层服务建立用户的标识。On login, the photo app establishes the identity of the user with the mid-tier service. 这种标识建立机制完全由应用程序决定。This mechanism of identity establishment is purely up to the application.

  5. 一旦建立标识,中间层服务就会基于标识请求权限。Once the identity is established, the mid-tier service requests permissions based on the identity.

  6. 中间层服务将资源令牌发送回手机应用。The mid-tier service sends a resource token back to the phone app.

  7. 手机应用可以继续使用该资源令牌以该资源令牌定义的权限按照该资源令牌允许的间隔直接访问 Cosmos DB 资源。The phone app can continue to use the resource token to directly access Cosmos DB resources with the permissions defined by the resource token and for the interval allowed by the resource token.

  8. 资源令牌到期后,后续请求收到 401 未经授权的异常。When the resource token expires, subsequent requests receive a 401 unauthorized exception. 此时,手机应用会重新建立标识,并请求新的资源令牌。At this point, the phone app re-establishes the identity and requests a new resource token.

    Azure Cosmos DB 资源令牌工作流

资源令牌的生成和管理由本机 Cosmos DB 客户端库处理;但是,如果使用 REST,必须构造请求/身份验证标头。Resource token generation and management are handled by the native Cosmos DB client libraries; however, if you use REST you must construct the request/authentication headers. 有关为 REST 创建身份验证标头的详细信息,请参阅 Cosmos DB 资源的访问控制或我们的 .NET SDKNode.js SDK 的源代码。For more information on creating authentication headers for REST, see Access Control on Cosmos DB Resources or the source code for our .NET SDK or Node.js SDK.

有关用于生成或代理资源令牌的中间层服务的示例,请参阅 ResourceTokenBroker 应用For an example of a middle tier service used to generate or broker resource tokens, see the ResourceTokenBroker app.

用户Users

Azure Cosmos DB 用户与 Cosmos 数据库相关联。Azure Cosmos DB users are associated with a Cosmos database. 每个数据库可以包含零个或更多 Cosmos DB 用户。Each database can contain zero or more Cosmos DB users. 以下代码示例展示了如何使用 Azure Cosmos DB .NET SDK v3 创建 Cosmos DB 用户。The following code sample shows how to create a Cosmos DB user using the Azure Cosmos DB .NET SDK v3.

//Create a user.
Database database = benchmark.client.GetDatabase("SalesDatabase");

User user = await database.CreateUserAsync("User 1");

备注

每个 Cosmos DB 用户都有一个 ReadAsync() 方法,可以使用此方法检索与用户关联的权限的列表。Each Cosmos DB user has a ReadAsync() method that can be used to retrieve the list of permissions associated with the user.

权限Permissions

权限资源与用户相关联,并在容器以及分区键级别进行分配。A permission resource is associated with a user and assigned at the container as well as partition key level. 每个用户可能包含零个或多个权限。Each user may contain zero or more permissions. 用户在尝试访问某个特定容器或访问特定分区键中的数据时需要一个安全令牌,权限资源提供对该安全令牌的访问权限。A permission resource provides access to a security token that the user needs when trying to access a specific container or data in a specific partition key. 权限资源提供两种可用的访问级别:There are two available access levels that may be provided by a permission resource:

  • 所有:用户对资源拥有完全权限。All: The user has full permission on the resource.
  • 读取:用户只能读取资源的内容,但无法对资源执行写入、更新或删除操作。Read: The user can only read the contents of the resource but cannot perform write, update, or delete operations on the resource.

备注

为了运行存储过程,用户必须对将在其中运行存储过程的容器具有全部权限。In order to run stored procedures the user must have the All permission on the container in which the stored procedure will be run.

如果对数据平面请求启用诊断日志,则会记录与该权限相对应的以下两个属性:If you enable the diagnostic logs on data-plane requests, the following two properties corresponding to the permission are logged:

  • resourceTokenPermissionId - 此属性指示已指定的资源令牌权限 ID。resourceTokenPermissionId - This property indicates the resource token permission Id that you have specified.

  • resourceTokenPermissionMode - 此属性指示在创建资源令牌时设置的权限模式。resourceTokenPermissionMode - This property indicates the permission mode that you have set when creating the resource token. 权限模式的值可以是“all”或“read”。The permission mode can have values such as "all" or "read".

有关创建权限的代码示例Code sample to create permission

以下代码示例演示如何创建权限资源、读取权限资源的资源令牌以及将权限与上面创建的用户关联。The following code sample shows how to create a permission resource, read the resource token of the permission resource, and associate the permissions with the user created above.

// Create a permission on a container and specific partition key value
Container container = client.GetContainer("SalesDatabase", "OrdersContainer");
user.CreatePermissionAsync(
    new PermissionProperties(
        id: "permissionUser1Orders",
        permissionMode: PermissionMode.All,
        container: benchmark.container,
        resourcePartitionKey: new PartitionKey("012345")));

有关读取用户权限的代码示例Code sample to read permission for user

下面的代码片段展示了如何检索与上面创建的用户关联的权限,并代表用户实例化一个新的 CosmosClient,作用域为单个分区键。The following code snippet shows how to retrieve the permission associated with the user created above and instantiate a new CosmosClient on behalf of the user, scoped to a single partition key.

//Read a permission, create user client session.
PermissionProperties permissionProperties = await user.GetPermission("permissionUser1Orders")

CosmosClient client = new CosmosClient(accountEndpoint: "MyEndpoint", authKeyOrResourceToken: permissionProperties.Token);

RBAC 和资源令牌之间的差异Differences between RBAC and resource tokens

使用者Subject RBACRBAC 资源令牌Resource tokens
身份验证Authentication 与 Azure Active Directory (Azure AD) 集成。With Azure Active Directory (Azure AD). 基于本机 Azure Cosmos DB 用户Based on the native Azure Cosmos DB users
将资源令牌与 Azure AD 集成需要额外的工作才能将 Azure AD 标识桥接到 Azure Cosmos DB 用户。Integrating resource tokens with Azure AD requires extra work to bridge Azure AD identities and Azure Cosmos DB users.
授权Authorization 基于角色:角色定义映射允许的操作,并且可以分配给多个标识。Role-based: role definitions map allowed actions and can be assigned to multiple identities. 基于权限:对于每个 Azure Cosmos DB 用户,需要分配数据访问权限。Permission-based: for each Azure Cosmos DB user, you need to assign data access permissions.
令牌范围Token scope AAD 令牌带有请求者的标识。An AAD token carries the identity of the requester. 此标识将与所有分配的角色定义匹配以执行授权。This identity is matched against all assigned role definitions to perform authorization. 资源令牌带有向特定 Azure Cosmos DB 资源上的特定 Azure Cosmos DB 用户授权的权限。A resource token carries the permission granted to a specific Azure Cosmos DB user on a specific Azure Cosmos DB resource. 不同资源的授权请求可能需要不同的令牌。Authorization requests on different resources may requires different tokens.
令牌刷新Token refresh Azure Cosmos DB SDK 在过期时自动刷新 AAD 令牌。The AAD token is automatically refreshed by the Azure Cosmos DB SDKs when it expires. 不支持资源令牌刷新。Resource token refresh is not supported. 资源令牌过期时,需要发出一个新令牌。When a resource token expires, a new one needs to be issued.

添加用户和分配角色Add users and assign roles

若要将 Azure Cosmos DB 帐户读者访问权限添加到用户帐户,请让订阅所有者在 Azure 门户执行以下步骤。To add Azure Cosmos DB account reader access to your user account, have a subscription owner perform the following steps in the Azure portal.

  1. 打开 Azure 门户,并选择 Azure Cosmos DB 帐户。Open the Azure portal, and select your Azure Cosmos DB account.
  2. 单击“访问控制(IAM)”选项卡,然后单击“+ 添加角色分配”。Click the Access control (IAM) tab, and then click + Add role assignment.
  3. 在“添加角色分配”窗格中的“角色”框中,选择“Cosmos DB 帐户读者角色”。In the Add role assignment pane, in the Role box, select Cosmos DB Account Reader Role.
  4. 在“分配其访问权限”框中,选择“Azure AD 用户、组或应用程序”。In the Assign access to box, select Azure AD user, group, or application.
  5. 在你想要授予访问权限的目录中选择用户、组或应用程序。Select the user, group, or application in your directory to which you wish to grant access. 可以通过显示名称、电子邮件地址或对象标识符搜索目录。You can search the directory by display name, email address, or object identifiers. 所选用户、组或应用程序会显示在所选成员列表中。The selected user, group, or application appears in the selected members list.
  6. 单击“保存” 。Click Save.

实体现在便可以读取 Azure Cosmos DB 资源。The entity can now read Azure Cosmos DB resources.

删除或导出用户数据Delete or export user data

借助 Azure Cosmos DB 数据库服务,你可搜索、选择、修改和删除数据库或容器中的任何数据。As a database service, Azure Cosmos DB enables you to search, select, modify and delete any data located in your database or containers. 但是,你有责任使用提供的 API 并定义查找和擦除任何个人数据所需的逻辑(如果需要)。It is however your responsibility to use the provided APIs and define logic required to find and erase any personal data if needed. 每个多模型 API(SQL、MongoDB、Gremlin、Cassandra、表)都包含不同的语言 SDK,这些 SDK 提供了各种用于搜索和基于自定义谓词删除数据的方法。Each multi-model API (SQL, MongoDB, Gremlin, Cassandra, Table) provides different language SDKs that contain methods to search and delete data based on custom predicates. 还可启用生存时间 (TTL)功能在指定时间段后自动删除数据,不会产生任何额外费用。You can also enable the time to live (TTL) feature to delete data automatically after a specified period, without incurring any additional cost.

备注

有关查看或删除个人数据的信息,请参阅 GDPR 的 Azure 数据使用者请求For information about viewing or deleting personal data, see Azure Data Subject Requests for the GDPR. 有关 GDPR 的详细信息,请参阅服务信任门户的 GDPR 部分For more information about GDPR, see the GDPR section of the Service Trust portal.

后续步骤Next steps