読者です 読者をやめる 読者になる 読者になる

Murayama blog.

プログラミングと、その次の話

AndroidでParse入門 - Roles -

元ネタ

こちらを参考にRolesについてまとめます。
https://parse.com/docs/android_guide#roles

前回の記事はこちら。
AndroidでParse入門 - Users - - Murayama blog.

Roles

ユーザをベースにしたアプリの規模が大きくなってくると、ユーザ単位のACLより大きな粒度でアクセス管理をしたくなるかもしれません。このような要件に対して、Parseはロールベースのアクセス管理を提供しています。ロールは、Parse上のデータに対して、論理的なユーザグループ単位でのアクセス権を提供します。ロールは、ユーザオブジェクトや他のロールオブジェクトを包括したオブジェクトです。ロールに付与されている権限は、対象となるユーザに暗黙的に付与されます。同様にロール内に含まれるロールの権限も付与されます。

たとえば、コンテンツをキュレーションするようなアプリケーションにおいては、何人かのユーザは"Moderators"として、他のユーザの投稿したコンテンツを更新したり、削除したりといった役割が必要になるでしょう。また、"Administrators"という役割のユーザは、"Moderators"と同等の権限を保持し、さららにシステム設定を変更できるようにする必要があるでしょう。これらのロールにユーザを追加することで、新規のユーザに手動でリソースへの権限を付与することなく、"Moderators"や"Administrators"とすることができます。

Parseは、このようなロールオブジェクトを表現するためにParseRoleというクラスを提供しています。ParseRoleはParseObjectのサブクラスです。そのため、フレキシブルなスキーマ、自動永続化機能、Key-ValueインタフェースといったParseObjectと同等の機能を保持しています。ParseObjectのすべてのメソッドを利用することができます。ParseRoleクラスは、ロール管理に必要な特別なメソッドが追加されています。

Properties

ParseRoleにはいくつかのプロパティが追加されています。

  • name: ロールの名前です。この値は必須項目であり、ロールを生成するときに設定する必要があります。ロールの名前には、半角英数字、スペース、ハイフン(-)、アンダースコア(_)を利用できます。この名前は、objectIdを使わずにロールを識別する方法として使用できます。
  • users: 関連するユーザの集合です。ロールに含まれる権限が適用される対象となります。
  • roles: 関連するロールの集合です。ロールに含まれる権限が適用される対象となります。

Security for Role Objects

ParseRoleは、Parse上の他のオブジェクトと同等のセキュリティスキーム(ACL)を使います。ただし、明示的にACLを設定する必要があります。一般的に、非常に高い権限(マスターユーザや管理者のような)を持ったユーザだけがロールを作成したり、更新したりすべきでしょう。そのような方針に従ってACLを定義する必要があります。ユーザにParseRoleへの書き込み権限を与えれば、そのユーザは、ロールに他のユーザを追加したり、ロールを削除したりすることもできるということを覚えておいてください。

ParseRoleを作成してみましょう。次のようになります。

// By specifying no write privileges for the ACL, we can ensure the role cannot be altered.
ParseACL roleACL = new ParseACL();
roleACL.setPublicReadAccess(true);
ParseRole role = new ParseRole("Administrator", roleACL);
role.saveInBackground();

ユーザやロールを追加できます。ParseRoleのusersプロパティ、rolesプロパティを通じて権限を適用することができます。

ParseRole role = new ParseRole(roleName, roleACL);
for (ParseUser user : usersToAddToRole) {
  role.getUsers().add(user)
}
for (ParseRole childRole : rolesToAddToRole) {
  role.getRoles().add(childRole);
}
role.saveInBackground();

ロールを変更する権限を持つユーザによって変更されることがあるので、ACLを割り当てるときには細心の注意を払ってください。

Security for Other Objects

アプリケーションで利用するロールを作成できたので、ロールに対して、ユーザに付与する権限をACLとして定義することができます。個々のParseObjectにはParseACLを設定できます。ParseACLで、対象オブジェクトに対して、読み込み権限、書き込み権限を付与するロールやユーザを定義することができます。

オブジェクトに読み込み権限、書き込み権限を与えるのは簡単です。ParseRoleを使う場合は次のようになります。

ParseRole moderators = /* Query for some ParseRole */;
ParseObject wallPost = new ParseObject("WallPost");
ParseACL postACL = new ParseACL();
postACL.setRoleWriteAccess(moderators);
wallPost.setACL(postACL);
wallPost.saveInBackground();

ACLにロールの名前を指定することで、Roleの問い合わせを減らすことができます。

ParseObject wallPost = new ParseObject("WallPost");
ParseACL postACL = new ParseACL();
postACL.setRoleWriteAccess("Moderators", true);
wallPost.setACL(postACL);
wallPost.save();


ロールベースのParseACLもまた、アプリケーションのデフォルトACLとして使用できます。書き込み権限を持つユーザだけにデータを保護することができます。アプリケーションに"Moderators"ロールをデフォルトACLに適用するには次のようになります。

ParseACL defaultACL = new ParseACL();
// Everybody can read objects created by this user
defaultACL.setPublicReadAccess(true);
// Moderators can also modify these objects
defaultACL.setRoleWriteAccess("Moderators");
// And the user can read and modify its own objects
ParseACL.setDefaultACL(defaultACL, true);

Role Hierarchy

ここまでで見てきたように、1つのロールに他のロールを含むことができます。つまり、2つのロールに親子関係を定義することができます。この結果、親のロールに付与された権限は、暗黙的にすべての子ロールに引き継がれることになります。

このような関連は、フォーラムのようなユーザコンテンツを管理するアプリケーションでよく見られます。ユーザのサブセットとして"Administrators"を定義し、"Administrators"には、アプリケーションの設定を調整したり、新しいフォーラムを作成したり、グローバルメッセージを設定したりといったハイレベルなアクセス制御を実装します。他のユーザのサブセットとして"Moderators"を定義し、コンテンツの品質を適切に保つための役割を定義します。ここで、"Administrator"の権限を持つユーザはまた"Moderator"の権限も持つべきでしょう。このような関連を定義するには、"Moderators"ロールの子ロールとして "Administrators"を作成します。次のようになるでしょう。

ParseRole administrators = /* Your "Administrators" role */;
ParseRole moderators = /* Your "Moderators" role */;
moderators.getRoles().add(administrators);
moderators.saveInBackground();