アクセス制御の洗練

的確なアクセス制御

先ほどの節で定義した基本的な ACL では、さまざまな規則を ACL 全体 (すべてのリソース) に対して適用しました。 しかし実際には、アクセス制御にはさまざまな例外がつきものですし、 もっと複雑なものになるでしょう。 Zend_Acl では、このような目的のためにも直感的で柔軟な方法で対応できます。

例にあげた CMS では大半のユーザを 'staff' グループでまとめて管理していました。 ここでは新しく 'marketing' グループを作成し、CMS のニュースレターや最新ニュースへのアクセスを許可させる必要があるでしょう。 このグループには、ニュースレターや最新ニュースの公開や保存権限があれば十分でしょう。

さらに 'staff' グループに対しては、ニュースの内容は閲覧できますが 最新ニュースの改変はできないようにします。 最後に、(administrators を含む) 全員は 'お知らせ' を保存できないようにします。これは、1 日から 2 日程度の有効期限しか持たないものだからです。

まず、ロールレジストリを変更してこれらの変更を反映させます。 'marketing' グループを作成して 'staff' と同様の基本権限を持たせることにしたので、 'marketing' を作成し、'staff' の権限を継承させます。

  1. // 新しいグループ marketing は staff の権限を引き継ぎます
  2. $acl->addRole(new Zend_Acl_Role('marketing'), 'staff');

次に、これらのアクセス制御は特定のリソース (例: "newsletter"、"latest news"、"announcement news") に限定されることに注目しましょう。ここで、これらのリソースを追加します。

  1. // 規則を適用するリソースを作成します
  2.  
  3. // ニュースレター
  4. $acl->addResource(new Zend_Acl_Resource('newsletter'));
  5.  
  6. // ニュース
  7. $acl->addResource(new Zend_Acl_Resource('news'));
  8.  
  9. // 最新ニュース
  10. $acl->addResource(new Zend_Acl_Resource('latest'), 'news');
  11.  
  12. // お知らせ
  13. $acl->addResource(new Zend_Acl_Resource('announcement'), 'news');

そして、次のような特別な規則を、ACL の該当範囲に適用します。

  1. // Marketing は、ニュースレターおよび最新ニュースを公開、保存できなければなりません
  2. $acl->allow('marketing',
  3.             array('newsletter', 'latest'),
  4.             array('publish', 'archive'));
  5.  
  6. // Staff (そして継承による marketing) は最新ニュースの改変ができません
  7. $acl->deny('staff', 'latest', 'revise');
  8.  
  9. // 全員 (administrators を含む) はお知らせを保存することができません
  10. $acl->deny(null, 'announcement', 'archive');

これで、最新の変更内容を反映した ACL への問い合わせが行えるようになります。

  1. echo $acl->isAllowed('staff', 'newsletter', 'publish') ?
  2.      "allowed" : "denied";
  3. // denied となります
  4.  
  5. echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
  6.      "allowed" : "denied";
  7. // allowed となります
  8.  
  9. echo $acl->isAllowed('staff', 'latest', 'publish') ?
  10.      "allowed" : "denied";
  11. // denied となります
  12.  
  13. echo $acl->isAllowed('marketing', 'latest', 'publish') ?
  14.      "allowed" : "denied";
  15. // allowed となります
  16.  
  17. echo $acl->isAllowed('marketing', 'latest', 'archive') ?
  18.      "allowed" : "denied";
  19. // allowed となります
  20.  
  21. echo $acl->isAllowed('marketing', 'latest', 'revise') ?
  22.      "allowed" : "denied";
  23. // denied となります
  24.  
  25. echo $acl->isAllowed('editor', 'announcement', 'archive') ?
  26.      "allowed" : "denied";
  27. // denied となります
  28.  
  29. echo $acl->isAllowed('administrator', 'announcement', 'archive') ?
  30.      "allowed" : "denied";
  31. // denied となります

アクセス制御の削除

ACL からひとつあるいは複数のアクセス規則を削除するには、 removeAllow() メソッドあるいは removeDeny() メソッドを使用します。 allow() および deny() と同様、NULL 値を指定すると すべてのロールやリソース、権限を表すことになります。

  1. // 最新ニュースの改変拒否を staff (そして継承による marketing) から削除します
  2. $acl->removeDeny('staff', 'latest', 'revise');
  3.  
  4. echo $acl->isAllowed('marketing', 'latest', 'revise') ?
  5.      "allowed" : "denied";
  6. // allowed となります
  7.  
  8. // ニュースレターの公開や保存の権限を、marketing から取り除きます
  9. $acl->removeAllow('marketing',
  10.                   'newsletter',
  11.                   array('publish', 'archive'));
  12.  
  13. echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
  14.      "allowed" : "denied";
  15. // denied となります
  16.  
  17. echo $acl->isAllowed('marketing', 'newsletter', 'archive') ?
  18.      "allowed" : "denied";
  19. // denied となります

上で説明したように、徐々に権限を変更していくこともできますが、 権限に対して NULL 値を設定すると、 このような変更を一括で行うことができます。

  1. // marketing に対して、最新のニュースへのアクセスを許可します
  2. $acl->allow('marketing', 'latest');
  3.  
  4. echo $acl->isAllowed('marketing', 'latest', 'publish') ?
  5.      "allowed" : "denied";
  6. // allowed となります
  7.  
  8. echo $acl->isAllowed('marketing', 'latest', 'archive') ?
  9.      "allowed" : "denied";
  10. // allowed となります
  11.  
  12. echo $acl->isAllowed('marketing', 'latest', 'anything') ?
  13.      "allowed" : "denied";
  14. // allowed となります
blog comments powered by Disqus