Drupal 7 におけるノードのアクセスコントロール

~ Controlling Nodes in Drupal 7 和訳 ~

Drupal のコンテンツのアクセスコントロールにはいくつかの方法があります。コアに組み込まれている機能、あるいは追加モジュールによって提供されるもの、またはいくつかの追加モジュールの組み合わせによって実現するものなどです。いくつかの機能は互いに互換性があります。

多彩な選択肢とそれらのトレードオフの関係をよく理解するためには、Drupal がこれに関して提供する2つの基本的なメカニズムを知っておく必要があります。hook_node_access() とグランツシステムです。

モジュールはこの2つの仕組みを利用して、サイトのアクセスコントロールを実装することが出来ます。

オペレーション

Drupal 7では、ノードには5つのオペレーションがあります。新規作成(Create)、読み込み(Read (or "view"))、更新(Update)、削除(Delete)、リスト(List)です。ここで重要なのは、読み込み(Read)とリスト(List)は別のオペレーションだということです。「読み込み」は単一のノードに作用し、「リスト」は条件にマッチした複数のノード一覧に作用します。「新規作成」オペレーションはもちろん、作成中のノードオブジェクトに作用します。

メカニズム

Drupal 7にはノードのアクセスコントロールにおける2つのシステムがあります。1つは hook_node_access() で、単一のノードオブジェクトに作用します。複数のモジュールがこのフックを実装し,特定のノードの各オペレーションにおいて、その表示を許可するか否かを制御することが出来ます。これはリクエストページの構築の都度行われ,モジュールはそれぞれの担当する条件処理により、アクセスの可否を判断します。

もうひとつはノードグランツシステムです。これは2つの場面で動作します。ひとつは hook_node_access() においてノードへのアクセスが許可も拒否もされなかった場合、もうひとつは、これが唯一のアクセス制御メカニズムとなる、ノードのリストオペレーションです。リストオペレーションは、ノードのオブジェクトレベルではなく、クエリレベルでのフィルタリングを必要とするため、唯一すべてのグループ/ノードの組み合わせをまとめたデータを作成し、データベースに格納、管理するグランツシステムによってフィルタリングされます。このように、グランツシステムはクエリの内容を直接操作し、ノードの抽出の段階でアクセス不可のものを排除します。「リストオペレーション」とは多くの場合、実際には Views での操作を意味します。

ここで重要なのは、ノードの存在をユーザーから完全に排除するには、グランツシステムが唯一の手段だということです。しかしこれはオールオアナッシングです。ノードグランツシステムを実装するモジュールが一旦インストールされると、システム内の全てのノードについて、そのノードのアクセス可否について関与する/しないに関わらず、少なくとも1つのレコードが node_access テーブルに挿入されます。これに対して hook_node_access() は、余計なオーバーヘッドなしに、より柔軟に動作します。

もしノードを完全に隠すことが重要であるなら、グランツシステムは唯一の選択です。もしそうでない場合、また Views によるコントロールで代替できる場合(例えば Foo タイプのノードだけを制限したい、View でそのノードタイプのリストは特定のロールのみに制限したい場合など)は、hook_node_access() によるアプローチのほうがより軽く、柔軟に対応できるでしょう。

あと考慮すべきは、複数のノードグランツモジュールをインストールした場合、うまく動作しない場合があることです。その場合ノードが全く表示されなかったり、表示されるべきでないノードが表示されたりします。このような場合は、これらの衝突を回避するために、いくつかのカスタムグルーコードが必要となります。幸いにも、Drupal 7 ではこのようなグルーコードは grant_alter フックで簡単に追加することが出来ます。

Tools

アクセスコントロールを活用するモジュールはたくさんあります。これらを使うときには、要望を満たすものかどうか、よく考えることが必要です。

hook_node_access() モジュール

Workbench
このモジュール(モジュール群)は、「セクション」という概念に基づいて、コンテンツの「新規作成」、「編集」、「削除」の権限を提供します。これはサイトのIA(情報構造)に関係なく、管理グループの階層構造を構築出来るポテンシャルを持っています。階層構造で最も一般的に使用されるのがタクソノミー、ボキャブラリですが、これに限りません。Workbench はあくまで管理用ツールのため、「読み込み」や「リスト」オペレーションには作用しませんが、非常に有用なモジュールです。
Organic Groups
Organic Groups は伝統的に重いアクセスモジュールですが、Drupal 7 ではきれいに設計されモジュール化されています。これはいくつかのノードといくつかのユーザーをひとつのグループとしてまとめることが出来ます。グループはいくつかのノード、ユーザー、あるいは他のエンティティで形成されます。ノードのアクセスコントロールについては、ユーザーは同じグループに属するノードを閲覧することが出来ます。逆に言うと、あるグループのノードはそのグループのメンバーにだけアクセスを許可されます。Drupal 7 では、ノードのパーミッションなどは、与えられたグループのコンテキストに合わせてカスタマイズすることが出来ます。これは、コンテンツタイプが「記事」の、あるグループのノードを作成できるのは、そのグループのメンバーだけということです。

ノードグランツモジュール

Domain Access
Domain Access は奇抜なモジュールです。このモジュールはノードグランツシステムを使いますが、ユーザーに応じてアクセスを制限するのではなく、リクエストされたドメインに応じてアクセスを制限します。Domain Access はひとつのコンテンツデータ、ひとつの管理データを複数のサイトで共有することを可能にします。これらは全てひとつの Drupal インスタンスですが、サイトごとにコンテンツをフィルタリングします。どのユーザーにどのコンテンツのアクセスを許可するかといった用途には向きませんが、これもノードグランツシステムを活用した例です。
Nodeaccess Nodereference and Nodeaccess Userreference
これらもまた個性的なモジュールですが表示、更新、削除のパーミッションをノードアクセスシステムを用いて付与します。コンテンツを Nodereference で参照しているノードについて、ユーザーがアクセス権を持っているかどうかで判断します。Organic Groups のような、ノードアクセスの複雑な階層構造を構築出来そうです。
Content Access
このモジュールはノードごと、またはコンテンツタイプごとにアクセスコントロールを設定できる最も新しいものです。ノードグランツシステムを利用します。Drupal 7 バージョンはまだベータ版です。
Taxonomy Access Control and TAC Lite
これらのモジュールはタクソノミータームに基づいてアクセス制御を行います。ユーザーは、アクセスが許可されたタームを持つノードのみアクセスが許可されます。Drupal 7 バージョンはまだ開発途上です。

その他

ファイルアクセスについてはどうでしょうか。多くの場合、ノードはパブリックに公開され、ファイルはそうではありません。Drupal 7 ではファイルフィールドごとに、パブリック設定/プライベート設定のいづれかを選択できます。パブリック設定にすると、そこに格納されたファイルには Drupal のシステムは全く関与せず、直接ダウンロードできます。つまり一切のアクセスコントロールがかかりません。多くの場合、パフォーマンス的な見地からこれは望ましいでしょう。

ファイルをプライベートに設定した場合、そのまま何もしなければ特に変化は無いように見えますが、動作としては hook_file_download_access() のチェックを行うPHPコールバックを通してアクセスされるようになります。Drupal 7 コアモジュールにはこのフックを実装しているものはありませんが、他のモジュールで実装する場合があります。例えば Field Permissions モジュールです。これは特定のフィールドのアクセスを制限できるようにするモジュールで、ファイルにアクセスしようとしているユーザーが、その権限を持っているかどうかを検証し、許可されている場合のみダウンロードを可能にします。

私は全てのモジュールについて、それがノードごとに、ファイルのダウンロードコントロールを行うものかどうか、意識して探したわけではありません。(もし他にもあれば、コメントでシェアしてください!)

もし Drupal サイト構築の情報をお探しなら、上に挙げたモジュールを使ってみてください。もし要望と違う、または特殊なアクセスコントロールモジュールを必要としているなら、Drupal Watchdog の #2 私の記事 "Hooked on Security" をご覧ください。では DrupalCon London でまた。

コア: 
Drupal7