2011年3月2日星期三

Re: [fw-mvc] Zend framework ACL - newbie help needed

Hi Matthew,

Thanks veyr much for your reply. I have a few questions, and we are having
trouble setting it up so I'll write that here as well:

Regarding $identity in your example - this is using Zend Auth as you said. For
now, I don't want to go into Zend Auth until I understand how to perform a
simple task on Zend Acl ;) Your examples have used $identity but if you think it
does simplify it please let me know, otherwise for now I am trying it without
the user of Zend Auth, as we are simply logging in the user with their username
+ user group ID (1, 2, or 3).
Further details:

* I was able to make the Zend_Acl object

But below parts are still unclear to me.
* Add roles to the Zend_Acl object
* Add resources to the Zend_Acl object
How can I match these roles with the currently existing users in my database?
For example I have following groups in my database.

1 Administrator
2 Regional Administrator
3 Content Manager

Basically, the above groups are "roles" . Administrator will have all privileges
in my CMS.

* Add resources to the Zend_Acl object
This is also not entirely clear to me. Should these be in the controller?
Eg-
http://framework.zend.com/wiki/pages/viewpage.action?pageId=39025#Zend_Acl%26MVCIntegration-AldemarBernal-4.DependenciesonOtherFrameworkComponents

$acl->add(new Zend_Acl_Resource('news')) (is "news" a controller? In where are
we defining the behavior of the $acl->add()? Is this inbuilt?)

Below is the the code I'm currently using. In the bootstrap.php :

Helper - library/My/Controller/Helper/
Plugin - library/My/Controller/Plugin/

/** Creating the ACL object */
require_once 'Zend/Acl.php';
$acl = new Zend_Acl();

/** Creating the Role object */
require_once 'Zend/Acl/Role.php';
$acl->addRole(new Zend_Acl_Role('staff'));
$acl->addRole(new Zend_Acl_Role('member'));


/**
* Creating resources:
* - News Controller
* Creating privileges:
* - Allow defaultRole to access news controller
* - Deny defaultRole to access add action of news controller
*/
require_once 'Zend/Acl/Resource.php';
$acl->add(new Zend_Acl_Resource('admin'))
->allow('staff', 'admin')
->deny('staff', 'admin', 'reports');


/** Registering the Plugin object */
//require_once 'Zend/Controller/Plugin/Acl.php';
//$front->registerPlugin(new Zend_Controller_Plugin_Acl($acl));


/* OK, do your stuff, front controller */
$frontController->dispatch();


I realise I need to go through the above again, but I'd like to post out a few
questions:

i) Are "plugin" files required? The link above mentions that we should upload a
certain ACL plugin + helper. Other tutorials mention this too. Is this correct?

ii) Because my boot strap has routes for the CMS ("AdminController") and front
end ("IndexController"), can I only define roles and resources within my CMS /
AdminController? Or must this kind of code be in the bootstrap.php file?

iii) I understand the concept - that a 'resource' (say, the reporting module in
the CMS) needs to be defined. A bunch of 'roles' also would be defined, i.e.
user groups ("AdministratorRole" would get all rights, and "ContentManagerRole"
would get a few rights).
Then, when I am actually at the controller action for my 'reporting module' for
example, what code do I put in to tell ZF that "we are in the reporting module
resource, so check the logged in user's rights and grant access if permitted"?

Many thanks,
Rishi


________________________________
From: Matthew Weier O'Phinney <matthew@zend.com>
To: fw-mvc@lists.zend.com
Sent: Mon, February 28, 2011 10:07:18 PM
Subject: Re: [fw-mvc] Zend framework ACL - newbie help needed

-- Rishi Daryanani <rishijd@yahoo.com> wrote
(on Monday, 28 February 2011, 06:06 AM -0800):
> I'm very new to ACL and it's not something we've tried below. Any guidance
>would
>
> be appreciated; I'm going to start with code experimentation but would like to

> know if I'm on the right track.
>
>
> We are using a custom developed CMS which is using ZF", and we have our front
> end website as well. The CMS uses a controller called "AdminController", and
>the
>
> front end only uses a controller called "IndexController". I want to introduce

> access control to this CMS. Therefore some user groups will be restricted to
> some areas of the CMS.
>
> Current potential solution :
>
> I'm thinking of achieving this functionality as described below.
>
> 1. Have a database table to store the type of the user.
> 2. Have a separate table to store the pages the user is allowed or not allowed.
>
> 3. Check in each page whether the user have the access or not and display the
> page accordingly.
>
> Which is the best way to implement this using Zend framework? "Zend_Auth" or
> "Zend_Acl" ?

Zend_Auth is used for authentication of a user; i.e., evaluating the
provided credentials to determine identity.

Zend_Acl is used for authorization; i.e., to determine whether a given
user has the rights to access a given resource.

What you describe above is the realm of Zend_Acl.

> I have looked in to the "Zend_Acl" and it sounds good, however
> could someone guide me - what is the procedure for implementing this? Here are

> the links I found:
> http://framework.zend.com/manual/en/zend.acl.introduction.html
> http://framework.zend.com/wiki/pages/viewpage.action?pageId=39025

The basic workflow is:

* Create a Zend_Acl object
* Add roles to the Zend_Acl object
* Add resources to the Zend_Acl object
* Create the permissions

Now, that said, there are a variety of ways to do this. You can do it
up-front -- i.e., define all roles, resources, and permissions in a
given object or in your bootstrap. If you have only a handful of ACLs to
create, this is a straight-forward approach.

Another approach is to add them as you need them.

As an example, when you grab the user identity during login or later
from the Zend_Auth session container, you might include the role in the
identity information. You can then add this to the ACL as you grab it:

$acl->addRole($identity->role);

You could also define an array of roles, and then one master role for
the user (which would indicate the user inherits all of those roles):

foreach ($identity->roles as $role) {
$acl->addRole($role);
}
$acl->addRole($identity->username, $identity->roles);

Later, when you grab your page, you might also include ACL information
in the page metadata. This allows you to setup the resource and
permissions ad-hoc. As an example, let's assume that a "page" object
might have the following in its structure:

public $identifier;
public $roles = array(
array('role' => array('read', 'write'))
);

$acl->addResource($page->identifier);
foreach ($page->roles as $role => $rights) {
if (!$acl->hasRole($role)) {
$acl->addRole($role);
}
$acl->allow($role, $page->identifier, $rights);
}

Then, you can test right there and then:

if (!$acl->isAllowed($identity->role, $page->identifier, $currentPrivilege))
{
throw new AclException;
}

This allows you some flexibility -- you don't have to define all ACLs up
front, and can grow the graph as your content grows. That said, it can
get tricky if you want to introduce role inheritance, so you have to
setup a strict convention of how the roles are stored.

Hope that helps get you started!

> The gist of my understanding is:
> - In the AdminController (or is it bootstrap.php) I have to define a set of
> Roles and Resources that are accessed/denied for those roles. This follows the

> above tutorial example. In my case, I need to add a new user role called "staff
>
> user" who will just have access to one function in the CMS, a basic "customer
> lookup" reporting function.
>
> - However I also need to check (in the "customer lookup" function) if the
> logged-in user has access rights to view this page. In all other pages, I need

> to DENY access rights actually, if the logged in user is a "staff user". Is
> there a tutorial like this which explains it for newbies? Or could someone
>guide
>
> me on what kind of code goes where?
>
> I'm not sure how I can tell ZF the name of the resource of each
>section/function
>
> of the CMS. For example, if I have a section called "Reports", and functions
> called
> - "Customer Lookup"
> - "Orders report"
> - "Members report"
>
> then what code would I put in for each of the above controller functions to
> assign a resource name and possibly a module/sub-resource name to each
>function?
>
> Many thanks,
> Rishi
>
>
>

--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

没有评论: