There is really one good answer. You need a controller plugin and use the preDispatch method to build and check your ACL. That is if your ACL is going to check module/controller/action access at all. Post routing, the request object has filtered the RequestURI into module/controller/action(s) so you can construct your ACL using this information. And between routing and dispatch leaves pre-dispatch as your only option.
The only choice at that point is which pre-dispatch you want to use. You can hitch pre-dispatch code as a method in each controller, but then you would have to duplicate your code a bunch of times for each controller which isn't very maintainable, so the best solution is to use a controller plugin since controller plugins are initialized prior to dispatching to a particular controller meaning your ACL code for creating and checking is in just one location.
Sure you could have an ACL controller, but then that means you have to force all requests through that controller prior to being redispatched again later. Plugins are so much simpler.
What I did was that I have a very simple plugin. It calls an ACL creation method followed by a simple isAllowed statement that checks the request against the ACL.
Where you place the factory code and so forth is really just a matter of personal preference. I didn't want to bloat up my plugin, so I moved the heavy lifting code to another factory class. And I felt that this is a library, which meant I placed it in /library/MyStuff (or something like that). Of course with 1.8+ you have to mess with namespaces to do that, but not a big deal.
My ACL factory in turn calls the database to gather info around hierarchical permissions and so forth, so that means the factory instantiates a Model_AAA (I felt it nice to have a simple model for all things authentication/authorization related), which then has a method for querying the database. I placed this model in the default (module) namespace. But put it where you want.
Last comment. After lots of wrestling over how to manage hierarchical permissions in a database structure, I settled on a nested set structure rather than a recursive structure. This takes a little getting used to, but it handles nesting of levels of resources so much better than trying to recurse many times. Google around and you should find some help on how to manage queries against a nested set. You can do lots of things such as gather the full parent branch of the tree from any given resource, etc. as well as find every sub tree from a given node. It is very powerful, and you can use this for group/role nesting as well if you have a complex group structure.
--Seth
Hi all, [1]
From: Jurian Sluiman [mailto:subscribe@juriansluiman.nl]
Sent: Thursday, August 20, 2009 2:56 AM
To: fw-auth@lists.zend.com; fw-mvc@lists.zend.com
Subject: Acl factory the MVC way
I'm trying to get the Auth+Acl combination working with very dynamic pages where pages are in categories (they can be inherited and act like a domain or something) and users are in groups (inherited as well).
Because of the complexity I'd like to use the factory method of the CodeUtopia post [2]. I'd like to do this completely MVC and the ZF1.8 / ZF1.9 way. This is my set up:
- A front controller plugin, checking each page view for the right Acl permission
- Some models in the default module (Model_Acl_User, Model_Acl_Group etc)
- An Acl stored in the registry for more control later in the process (e.g. permission to edit etc)
- A factory to create the Acl with only the roles and resources necessary
Now the problem: where should I place the factory??? It's not a model, it's not a front controller plugin, an application resource doesn't seem right to me either. A factory class in my own library is an option, but is it the best option? What about an AclController in the default module?
I'd like to hear you opinion about this problem.
Thanks in advance,
Jurian Sluiman
[1]I hope you don't mind, but it's Acl in MVC so I sent it to both lists trying to get the best of both worlds
[2]http://codeutopia.net/blog/2009/02/18/zend_acl-part-3-creating-and-storing-dynamic-acls/
--
Jurian Sluiman
Soflomo.com
没有评论:
发表评论