DocumentDB-アクセス制御

DocumentDBは、DocumentDBリソースへのアクセスを制御するための概念を提供します。DocumentDBリソースへのアクセスは、マスターキートークンまたはリソーストークンによって管理されます。リソーストークンに基づく接続は、トークンで指定されたリソースにのみアクセスでき、他のリソースにはアクセスできません。リソーストークンは、ユーザーのアクセス許可に基づいています。

  • 最初に1人以上のユーザーを作成し、これらはデータベースレベルで定義されます。

  • 次に、各ユーザーにアクセスを許可するリソースに基づいて、ユーザーごとに1つ以上のアクセス許可を作成します。

  • 各権限は、特定のリソースへの読み取り専用またはフルアクセスのいずれかを許可し、データベース内の任意のユーザーリソースにすることができるリソーストークンを生成します。

  • ユーザーはデータベースレベルで定義され、権限はユーザーごとに定義されます。

  • ユーザーと権限は、データベース内のすべてのコレクションに適用されます。

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;
}

Step 1−作成するリソースと同様に、AliceとTomの2人のユーザーを作成し、目的のIDを使用して定義オブジェクトを作成し、createメソッドを呼び出します。この場合、データベースのSelfLinkとuserDefinitionを使用してCreateUserAsyncを呼び出します。新しく作成されたユーザーオブジェクトを取得したリソースプロパティから結果を取得します。

次に、これら2人の新しいユーザーをデータベースに表示します。

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); 
}

Step 2−データベースのUsersLinkに対してCreateUserQueryを呼び出して、すべてのユーザーのリストを取得します。次に、それらをループして、それらのプロパティを表示します。

次に、最初にそれらを作成する必要があります。したがって、MyCollectionコレクションへの読み取り/書き込みアクセス許可をAliceに許可したいのに、Tomはコレクション内のドキュメントしか読み取れないとしましょう。

await CreatePermission(client, alice, "Alice Collection Access", PermissionMode.All,
   collection);
	
await CreatePermission(client, tom, "Tom Collection Access", PermissionMode.Read,
   collection);

Step 3− MyCollectionコレクションであるリソースに対するアクセス許可を作成して、そのリソースをSelfLinkにする必要があります。

Step 4 −次に、アリスの場合はこのコレクションにPermission.Allを作成し、トムの場合はこのコレクションに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が含まれます。許可を得て。

Step 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); 
}

今回は、ユーザーのアクセス許可リンクに対するアクセス許可クエリであり、ユーザーに返された各アクセス許可を一覧表示するだけです。

アリスとトムの権限を削除しましょう。

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); 
}

Step 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); 
}

Step 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