Programmer's Reference Guide

導入

アクセス制御の洗練

的確なアクセス制御

先ほどの節で定義した基本的な 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 となります

導入

Comments

1.
$acl->allow('marketing',

array('newsletter', 'latest'),
array('publish', 'archive'));
Can the above statement be rewritten as
2.
$acl->allow('marketing','newsletter',array('publish', 'archive'));
$acl->allow('marketing','latest',array('publish', 'archive'));

I tested it. It didn't give any error but i'm asking this because does 2. will allocate more memory space then 1.?

Regards,
Shah Mubashir Hussain.
1.
$acl->allow('marketing',

array('newsletter', 'latest'),
array('publish', 'archive'));
Can the above statement be rewritten as
2.
$acl->allow('marketing','newsletter',array('publish', 'archive'));
$acl->allow('marketing','latest',array('publish', 'archive'));

I tested it. It didn't give any error but i'm asking this because does 2. will allocate more memory space then 1.?

Regards,
Shah Mubashir Hussain.
any suggestins on how to implement acl in a multitenant system where the roleid is unique within the scope of the tenant. the acl is complaining about the role already being added. i could think of appending the tenantid to the roleid before adding the role to the acl.
I wrote a simple two part tutorial on implementing Zend_Auth and Zend_ACL. Check it out at <a href="http://blog.intervestcorp.com/?p=12">blog.intervestcorp.com</a>.

+ Add A Comment

Please do not report issues via comments; use the ZF Issue Tracker.

If you have a JIRA/Crowd account, we suggest you login first before commenting.

  • BBCode is allowed in the comment markup

  • Select a Version

    Languages Available

    Components

    Search the Manual