みな様がLiferayカスタマイズをする時、権限周りのメソッド"シグネチャーに困ったことがありますか?例えば、PermissionCheckerとか、Liferay 7.1から新規したヘルパークラスModelResourcePermission.javaとPortletResourcePermission.javaなどにおいてはメソッド中、このような定義がよく見えます。
//PermissionChecker public boolean hasOwnerPermission(long companyId, String name, long primKey, long ownerId, String actionId); public boolean hasPermission(Group group, String name, long primKey, String actionId); // ModelResourcePermission public void check(PermissionChecker permissionChecker, long primaryKey, String actionId); public void check(PermissionChecker permissionChecker, T model, String actionId); // PortletResourcePermission public void check(PermissionChecker permissionChecker, Group group, String actionId);
どの場面でどのメソッドを利用しますか?利用の際どの値をメソッドに与えますか?そのメソッドシグネチャーはLiferayの権限管理の関係はどうですか?今回はこの権限周りにいて考察しようと思います。
ちなみに、みなさまはLiferayオフィシャルブログの権限関連記事を読んだことがありますか?この記事はLiferayのロールと権限の基本関係を説明しているのでぜひおすすめです。
Liferayの権限
みな様のご存知通り、Liferayの権限システムには、ポートレットリソースまたはモデルリソース毎の粒度で行われています。従って:
- Liferayリソース(Blog、JournalArticleまたはDLFileEntryなど)の初期パーミッションは全部ResourceLocalService.addResourcesに介してResourcePermissionテーブルにレコードを作成している(例:JournalArticleLocalServiceImpl.java)。
- 逆に、PermissionCheckerがユーザの権限をチェックする際、同じくResourceLocalService.hasUserPermissionなどのメソッドを利用している(例:AdvancedPermissionChecker.java)。
すなわち、Liferayでは、ResourcePermissionとPermissionCheckerを利用し本当のResourcePermissionテーブルの詳細情報を隠しています。Liferayの権限システムを深く理解したい場合、ResourcePermissionテーブルとリソース権限の関係を考察しないといけない理由はそこにあります。
ResourcePermissionテーブル
Liferayが行なっている権限管理はロールベースアクセス制御(RBAC)方式のため、最終的にデータベースに記入するレコードは以下の内容になります:
- あるロールが
- あるリソースに対して
- どんな操作が許可される
ResourcePermissionテーブルはその三つの情報を含んでいます。上記Liferayオフィシャルブログ記事を参考して具体的に整理してみましょう。
- name: リソース名
- ポートレットリソース:ポートレットキー
- モデルリソース:モデル名
- primKey: リソースID(権限範囲)
- 全Liferayインスタンス有効権限: companyId
- グループ内有効: groupId
- 具体的なリソースに対する権限:
- モデルリソース: リソースprimKey
- ポートレットリソース: layoutId + _LAYOUT_ + portletId
- scope: 権限の範囲
- 1: 全Liferayインスタンスに有効
- 2: グループ内のみ有効
- 3: グループテンプレート(サイト、組織)内のみ有効
- 4: 具体的なリソースインスタンスに対する権限
- roleId: ロールID
- actionId: 権限が許可する操作
- actionIdのbitwise定義はLiferayオフィシャルブログ記事を参考する
まとめると、以下のグラフのようにRBACに必要な情報をレコードで格納しています。
それでは、具体的にどのような内容が格納されるのかを確認しましょう。
考察
今回はLiferayの標準モジュールBlogポートレットを利用してResourcePermissionテーブル中一般ロールに対する権限の表現を確認しましょう。
一般ロール x モデルリソース
以下の準備を行いましょう:
- 一般ロールblog_roleを作成する
- blog_roleを開いて、権限定義に
- ブログ/エントリー追加する権限を追加する
- ブログのエントリ/表示権限を追加する
- デフォルトサイトにブログポートレットを置き、その中にpermisison-blogというブログエンティティを作成する
- permission-blogの権限定義に、
- blog_roleに表示と更新を追加する
その後、ロールとResourcePermissionテーブルで確認しましょう。
select roleId, name, type_ from Role_ where name = "blog_role"; select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds from ResourcePermission where roleId = 50867;
結果は以下の通りです。
roleId | ロール名 | ロールtype |
---|---|---|
50867 | blog_role | 1 |
ID | リソース名 | scope | primKey | primKeyId | roleId | 操作 |
---|---|---|---|---|---|---|
5207 | com.liferay.blogs | 1 | 20099 | 20099 | 50867 | 2 |
5218 | com.liferay.blogs.model.BlogsEntry | 1 | 20099 | 20099 | 50867 | 1 |
5219 | com.liferay.blogs.model.BlogsEntry | 4 | 50893 | 50893 | 50867 | 33 |
では、その結果はどのような権限を表すのかについて考察しましょう。
ID | ロール | どんなリソース | どの操作※ |
---|---|---|---|
5207 | blog_role | scope=1: liferayインスタンス20099中の全てcom.liferay.blogs | ADD_ENTRY |
5218 | blog_role | scope=1: liferayインスタンス20099中の全てcom.liferay.blogs.model.BlogsEntry | VIEW |
5219 | blog_role | scope=4: id=50893のcom.liferay.blogs.model.BlogsEntryインスタンス | VIEW + UPDATE |
一般ロール x ポートレットリソース
続いて、以下の準備を行いましょう。
- blog_roleを開いて、権限定義に
- アプリケーション権限/ページに追加する権限を追加する
- デフォルトサイトのブログポートレットに
- ポートレット権限設定を開いてblog_roleに設定権限を追加する
それ後、ロールとResourcePermissionテーブルで確認しましょう。
select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds from ResourcePermission where roleId = 50867;
結果は以下の通りです(重複レコードを除外します)。
ID | リソース名 | scope | primKey | primKeyId | roleId | 操作 |
---|---|---|---|---|---|---|
5222 | com_liferay_blogs_web_portlet_BlogsPortlet | 1 | 20099 | 20099 | 50867 | 2 |
5223 | com_liferay_blogs_web_portlet_BlogsPortlet | 4 | 38656_LAYOUT_com_liferay_blogs_web_portlet_BlogsPortlet | 0 | 50867 | 4 |
では、その結果はどのような権限を表すのかについて考察しましょう。
ID | ロール | どんなリソース | どの操作 |
---|---|---|---|
5222 | blog_role | scope=1: liferayインスタンス20099中の全てBlogsPortlet | ADD_TO_PAGE |
5219 | blog_role | scope=4: id=38656のレイアウト上のBlogsPortlet | CONFIGURATION |
まとめ
ここまでチェックすると、権限を与えられるリソースは三種類があることがわかりました。
- 具体的なインスタンスを持っていないリソース
- そのモデルクラスは存在しないためインスタンス化できないため仮想モデルとして認識します。
- 例:リソースcom.liferay.blogsはLiferayブログその概念を表すものと認識できます。
- そのリソースに与えられる権限は、具体的なブログエンティティに関係ありません。
- 権限例:新規作成、パーミッション設定、ブログの購読
- 特定できるインスタンスに適用しないため、scopeは4になれません。
- primKeyは権限が適用される範囲の対象を表します。
- scope=1の場合、primKeyはliferayインスタンスIDです。
- 任意ある種類のインスタンス化可能なリソース
- 対象は任意Liferayモデルまたはポートレット
- 例:リソースcom.liferay.blogs.model.BlogsEntry, scope=1は全Liferayインスタンス中の任意Liferayブログを表し、そのリソースに与える権限は全Liferayインスタンス中のブログで有効となります。
- 例:リソースcom_liferay_blogs_web_portlet_BlogsPortlet, scope=1は全Liferayインスタンス中任意ブログポートレットを表し、そのリソースに与える権限は全Liferayインスタンス中のブログポートレットで有効となります。
- 操作は具体的にインスタンスに対するアクションです。
- 例:参照、更新、削除、コメント追加、ポートレット追加
- 任意インスタンスに適応する権限のため、scopeは4になれません。
- primKeyは権限が適用される範囲の対象を表します。
- scope=1の場合、primKey=LiferayインスタンスID
- 特定したリソース
- 対象は任意Liferayモデルまたはポートレット
- 例:リソースcom.liferay.blogs.model.BlogsEntry, scope=4はprimKeyに指定するブログエンティティと認識します。その権限はその特定のブログエンティティのみで有効です。
- 例:リソースcom_liferay_blogs_web_portlet_BlogsPortlet, scope=4はprimKeyに指定するブログポートレットと認識します。その権限はその特定のブログポートレットので有効です。
- 操作は具体的にインスタンスに対するアクションです。
- primKeyは特定インスタンスのIDになります。
- モデルリソースの場合、primKey=モデルID
- ポートレットリソースの場合、primKey=layoutId + _LAYOUT_ + ポートレットキー
次回、サイトロールなどグループロールに与える権限を考察しようと思います。
※ actionIdの内容は以下のsqlで取得できます。
select name, actionId, bitwiseValue from ResourceAction where name="com.liferay.blogs" and bitwiseValue = 2; select name, actionId, bitwiseValue from ResourceAction where name="com.liferay.blogs.model.BlogsEntry" and (bitwiseValue = 1 or bitwiseValue=32); select name, actionId, bitwiseValue from ResourceAction where name="com_liferay_blogs_web_portlet_BlogsPortlet " and (bitwiseValue = 2 or bitwiseValue = 4);
リソース名 | 操作 | bitwiseValue |
---|---|---|
com.liferay.blogs | ADD_ENTRY | 2 |
com.liferay.blogs.model.BlogsEntry | VIEW | 1 |
com.liferay.blogs.model.BlogsEntry | UPDATE | 32 |
com_liferay_blogs_web_portlet_BlogsPortlet | ADD_TO_PAGE | 2 |
com_liferay_blogs_web_portlet_BlogsPortlet | CONFIGURATION | 4 |
No comments:
New comments are not allowed.