📜  DocumentDB-访问控制

📅  最后修改于: 2020-11-28 13:52:21             🧑  作者: Mango


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 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和一个PermissionMode(可以是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