DocumentDB – 访问控制
DocumentDB – 访问控制
DocumentDB 提供了控制对 DocumentDB 资源的访问的概念。对 DocumentDB 资源的访问由主密钥令牌或资源令牌管理。基于资源令牌的连接只能访问令牌指定的资源,不能访问其他资源。资源令牌基于用户权限。
-
首先创建一个或多个用户,这些用户是在数据库级别定义的。
-
然后,根据您希望允许每个用户访问的资源,为每个用户创建一个或多个权限。
-
每个权限都会生成一个资源令牌,允许对给定资源进行只读或完全访问,并且可以是数据库中的任何用户资源。
-
用户是在数据库级别定义的,并且为每个用户定义权限。
-
用户和权限适用于数据库中的所有集合。
让我们看一个简单的例子,在这个例子中我们将学习如何定义用户和权限以在 DocumentDB 中实现细粒度的安全性。
我们将从一个新的 DocumentClient 开始并查询 myfirstdb 数据库。
private static async Task CreateDocumentClient() { // Create a new instance of the DocumentClient using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'myfirstdb'").AsEnumerable().First(); collection = client.CreateDocumentCollectionQuery(database.CollectionsLink, "SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First(); var alice = await CreateUser(client, "Alice"); var tom = await CreateUser(client, "Tom"); } }
以下是 CreateUser 的实现。
private async static Task<User> CreateUser(DocumentClient client, string userId) { Console.WriteLine(); Console.WriteLine("**** Create User {0} in {1} ****", userId, database.Id); var userDefinition = new User { Id = userId }; var result = await client.CreateUserAsync(database.SelfLink, userDefinition); var user = result.Resource; Console.WriteLine("Created new user"); ViewUser(user); return user; }
第 1 步– 创建两个用户 Alice 和 Tom 就像我们创建的任何资源一样,我们构造一个具有所需 Id 的定义对象并调用 create 方法,在这种情况下,我们使用数据库的 SelfLink 和 userDefinition 调用 CreateUserAsync。我们从我们获取新创建的用户对象的资源属性中取回结果。
现在在数据库中看到这两个新用户。
private static void ViewUsers(DocumentClient client) { Console.WriteLine(); Console.WriteLine("**** View Users in {0} ****", database.Id); var users = client.CreateUserQuery(database.UsersLink).ToList(); var i = 0; foreach (var user in users) { i++; Console.WriteLine(); Console.WriteLine("User #{0}", i); ViewUser(user); } Console.WriteLine(); Console.WriteLine("Total users in database {0}: {1}", database.Id, users.Count); } private static void ViewUser(User user) { Console.WriteLine("User ID: {0} ", user.Id); Console.WriteLine("Resource ID: {0} ", user.ResourceId); Console.WriteLine("Self Link: {0} ", user.SelfLink); Console.WriteLine("Permissions Link: {0} ", user.PermissionsLink); Console.WriteLine("Timestamp: {0} ", user.Timestamp); }
第 2 步– 针对数据库的 UsersLink 调用 CreateUserQuery 以检索所有用户的列表。然后遍历它们并查看它们的属性。
现在我们必须首先创建它们。因此,假设我们希望允许 Alice 对 MyCollection 集合进行读/写权限,但 Tom 只能读取集合中的文档。
await CreatePermission(client, alice, "Alice Collection Access", PermissionMode.All, collection); await CreatePermission(client, tom, "Tom Collection Access", PermissionMode.Read, collection);
第 3 步– 创建对 MyCollection 集合资源的权限,因此我们需要为该资源获取 SelfLink。
第 4 步– 然后在此集合上为 Alice 创建一个 Permission.All,并为 Tom 在此集合上创建一个 Permission.Read。
以下是 CreatePermission 的实现。
private async static Task CreatePermission(DocumentClient client, User user, string permId, PermissionMode permissionMode, string resourceLink) { Console.WriteLine(); Console.WriteLine("**** Create Permission {0} for {1} ****", permId, user.Id); var permDefinition = new Permission { Id = permId, PermissionMode = permissionMode, ResourceLink = resourceLink }; var result = await client.CreatePermissionAsync(user.SelfLink, permDefinition); var perm = result.Resource; Console.WriteLine("Created new permission"); ViewPermission(perm); }
正如您现在应该期待的那样,我们通过为新权限创建一个定义对象来实现这一点,其中包括一个 Id 和一个权限模式,它可以是 Permission.All 或 Permission.Read,以及被保护的资源的 SelfLink经许可。
第 5 步– 调用 CreatePermissionAsync 并从结果中的资源属性获取创建的权限。
查看创建的权限,下面是ViewPermissions的实现。
private static void ViewPermissions(DocumentClient client, User user) { Console.WriteLine(); Console.WriteLine("**** View Permissions for {0} ****", user.Id); var perms = client.CreatePermissionQuery(user.PermissionsLink).ToList(); var i = 0; foreach (var perm in perms) { i++; Console.WriteLine(); Console.WriteLine("Permission #{0}", i); ViewPermission(perm); } Console.WriteLine(); Console.WriteLine("Total permissions for {0}: {1}", user.Id, perms.Count); } private static void ViewPermission(Permission perm) { Console.WriteLine("Permission ID: {0} ", perm.Id); Console.WriteLine("Resource ID: {0} ", perm.ResourceId); Console.WriteLine("Permission Mode: {0} ", perm.PermissionMode); Console.WriteLine("Token: {0} ", perm.Token); Console.WriteLine("Timestamp: {0} ", perm.Timestamp); }
这一次,它是针对用户权限链接的权限查询,我们只是列出为用户返回的每个权限。
让我们删除 Alice 和 Tom 的权限。
await DeletePermission(client, alice, "Alice Collection Access"); await DeletePermission(client, tom, "Tom Collection Access");
以下是 DeletePermission 的实现。
private async static Task DeletePermission(DocumentClient client, User user, string permId) { Console.WriteLine(); Console.WriteLine("**** Delete Permission {0} from {1} ****", permId, user.Id); var query = new SqlQuerySpec { QueryText = "SELECT * FROM c WHERE c.id = @id", Parameters = new SqlParameterCollection { new SqlParameter { Name = "@id", Value = permId } } }; Permission perm = client.CreatePermissionQuery(user.PermissionsLink, query) .AsEnumerable().First(); await client.DeletePermissionAsync(perm.SelfLink); Console.WriteLine("Deleted permission {0} from user {1}", permId, user.Id); }
步骤 6 – 要删除权限,通过权限 ID 查询以获取 SelfLink,然后使用 SelfLink 删除权限。
接下来,让我们删除用户本身。让我们删除这两个用户。
await DeleteUser(client, "Alice"); await DeleteUser(client, "Tom");
以下是 DeleteUser 的实现。
private async static Task DeleteUser(DocumentClient client, string userId) { Console.WriteLine(); Console.WriteLine("**** Delete User {0} in {1} ****", userId, database.Id); var query = new SqlQuerySpec { QueryText = "SELECT * FROM c WHERE c.id = @id", Parameters = new SqlParameterCollection { new SqlParameter { Name = "@id", Value = userId } } }; User user = client.CreateUserQuery(database.SelfLink, query).AsEnumerable().First(); await client.DeleteUserAsync(user.SelfLink); Console.WriteLine("Deleted user {0} from database {1}", userId, database.Id); }
第 7 步– 首先查询以获取她的 SelfLink,然后调用 DeleteUserAsync 删除她的用户对象。
以下是我们调用上述所有任务的 CreateDocumentClient 任务的实现。
private static async Task CreateDocumentClient() { // Create a new instance of the DocumentClient using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'myfirstdb'").AsEnumerable().First(); collection = client.CreateDocumentCollectionQuery(database.CollectionsLink, "SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First(); ViewUsers(client); var alice = await CreateUser(client, "Alice"); var tom = await CreateUser(client, "Tom"); ViewUsers(client); ViewPermissions(client, alice); ViewPermissions(client, tom); string collectionLink = client.CreateDocumentCollectionQuery(database.SelfLink, "SELECT VALUE c._self FROM c WHERE c.id = 'MyCollection'") .AsEnumerable().First().Value; await CreatePermission(client, alice, "Alice Collection Access", PermissionMode.All, collectionLink); await CreatePermission(client, tom, "Tom Collection Access", PermissionMode.Read, collectionLink); ViewPermissions(client, alice); ViewPermissions(client, tom); await DeletePermission(client, alice, "Alice Collection Access"); await DeletePermission(client, tom, "Tom Collection Access"); await DeleteUser(client, "Alice"); await DeleteUser(client, "Tom"); } }
编译并执行上述代码后,您将收到以下输出。
**** View Users in myfirstdb **** Total users in database myfirstdb: 0 **** Create User Alice in myfirstdb **** Created new user User ID: Alice Resource ID: kV5oAC56NwA= Self Link: dbs/kV5oAA==/users/kV5oAC56NwA=/ Permissions Link: dbs/kV5oAA==/users/kV5oAC56NwA=/permissions/ Timestamp: 12/17/2015 5:44:19 PM **** Create User Tom in myfirstdb **** Created new user User ID: Tom Resource ID: kV5oAALxKgA= Self Link: dbs/kV5oAA==/users/kV5oAALxKgA=/ Permissions Link: dbs/kV5oAA==/users/kV5oAALxKgA=/permissions/ Timestamp: 12/17/2015 5:44:21 PM **** View Users in myfirstdb **** User #1 User ID: Tom Resource ID: kV5oAALxKgA= Self Link: dbs/kV5oAA==/users/kV5oAALxKgA=/ Permissions Link: dbs/kV5oAA==/users/kV5oAALxKgA=/permissions/ Timestamp: 12/17/2015 5:44:21 PM User #2 User ID: Alice Resource ID: kV5oAC56NwA= Self Link: dbs/kV5oAA==/users/kV5oAC56NwA=/ Permissions Link: dbs/kV5oAA==/users/kV5oAC56NwA=/permissions/ Timestamp: 12/17/2015 5:44:19 PM Total users in database myfirstdb: 2 **** View Permissions for Alice **** Total permissions for Alice: 0 **** View Permissions for Tom **** Total permissions for Tom: 0 **** Create Permission Alice Collection Access for Alice **** Created new permission Permission ID: Alice Collection Access Resource ID: kV5oAC56NwDON1RduEoCAA== Permission Mode: All Token: type=resource&ver=1&sig=zB6hfvvleC0oGGbq5cc67w==;Zt3Lx Ol14h8pd6/tyF1h62zbZKk9VwEIATIldw4ZyipQGW951kirueAKdeb3MxzQ7eCvDfvp7Y/ZxFpnip/D G JYcPyim5cf+dgLvos6fUuiKSFSul7uEKqp5JmJqUCyAvD7w+qt1Qr1PmrJDyAIgbZDBFWGe2VT9FaBH o PYwrLjRlnH0AxfbrR+T/UpWMSSHtLB8JvNFZNSH8hRjmQupuTSxCTYEC89bZ/pS6fNmNg8=; Timestamp: 12/17/2015 5:44:28 PM **** Create Permission Tom Collection Access for Tom **** Created new permission Permission ID: Tom Collection Access Resource ID: kV5oAALxKgCMai3JKWdfAA== Permission Mode: Read Token: type=resource&ver=1&sig=ieBHKeyi6EY9ZOovDpe76w==;92gwq V4AxKaCJ2dLS02VnJiig/5AEbPcfo1xvOjR10uK3a3FUMFULgsaK8nzxdz6hLVCIKUj6hvMOTOSN8Lt 7 i30mVqzpzCfe7JO3TYSJEI9D0/5HbMIEgaNJiCu0JPPwsjVecTytiLN56FHPguoQZ7WmUAhVTA0IMP6 p jQpLDgJ43ZaG4Zv3qWJiO689balD+egwiU2b7RICH4j6R66UVye+GPxq/gjzqbHwx79t54=; Timestamp: 12/17/2015 5:44:30 PM **** View Permissions for Alice **** Permission #1 Permission ID: Alice Collection Access Resource ID: kV5oAC56NwDON1RduEoCAA== Permission Mode: All Token: type=resource&ver=1&sig=BSzz/VNe9j4IPJ9M31Mf4Q==;Tcq/B X50njB1vmANZ/4aHj/3xNkghaqh1OfV95JMi6j4v7fkU+gyWe3mJasO3MJcoop9ixmVnB+RKOhFaSxE l P37SaGuIIik7GAWS+dcEBWglMefc95L2YkeNuZsjmmW5b+a8ELCUg7N45MKbpzkp5BrmmGVJ7h4Z4pf D rdmehYLuxSPLkr9ndbOOrD8E3bux6TgXCsgYQscpIlJHSKCKHUHfXWBP2Y1LV2zpJmRjis=; Timestamp: 12/17/2015 5:44:28 PM Total permissions for Alice: 1 **** View Permissions for Tom **** Permission #1 Permission ID: Tom Collection Access Resource ID: kV5oAALxKgCMai3JKWdfAA== Permission Mode: Read Token: type=resource&ver=1&sig=NPkWNJp1mAkCASE8KdR6PA==;ur/G2 V+fDamBmzECux000VnF5i28f8WRbPwEPxD1DMpFPqYcu45wlDyzT5A5gBr3/R3qqYkEVn8bU+een6Gl j L6vXzIwsZfL12u/1hW4mJT2as2PWH3eadry6Q/zRXHAxV8m+YuxSzlZPjBFyJ4Oi30mrTXbBAEafZhA 5 yvbHkpLmQkLCERy40FbIFOzG87ypljREpwWTKC/z8RSrsjITjAlfD/hVDoOyNJwX3HRaz4=; Timestamp: 12/17/2015 5:44:30 PM Total permissions for Tom: 1 **** Delete Permission Alice Collection Access from Alice **** Deleted permission Alice Collection Access from user Alice **** Delete Permission Tom Collection Access from Tom **** Deleted permission Tom Collection Access from user Tom **** Delete User Alice in myfirstdb **** Deleted user Alice from database myfirstdb **** Delete User Tom in myfirstdb **** Deleted user Tom from database myfirstdb