Because of the way Agavi's SecurityFilter
works Agavi's Role-Based Access Control (RBAC) and the user credential
handling in general assume that the user has been authenticated. By
default if the user is not authenticated no credentials are checked.
This can become an issue if you want to build an application where the
same action can be public in one set-up but requires a certain
credential in another. For example a project management software's
calendar could be public in one firm but protected in another.
To enable role-based access control for unauthenticated users you
need to do two things - grant a role for unauthenticated users and put
some logic into your base action's isSecure()
method.
class MyProjectUser extends AgaviRbacSecurityUser
{
public function initialize(AgaviContext $context, array $parameters = array())
{
parent::initialize($context, $parameters);
if(!$this->authenticated) {
$this->grantRole('unauthenticated');
}
}class MyProjectBaseAction extends AgaviAction
{
public function isSecure()
{
$cred = $this->getCredentials();
return $cred && !$this->getContext()->getUser()->hasCredentials($cred);
}
}The first bit is pretty obvious.
AgaviRbacSecurityUser initializes unauthenticated
users to have no roles but we want to override this and grant them a
special role called . The
code for unauthenticatedisSecure() then again might require
some reasoning. The action is marked as secure only if the user doesn't
have the required credential. What this means is that if the user is
authenticated but doesn't have the required credential
%actions.secure_action% is triggered. If the user is not
authenticated and unauthenticated role doesn't allow this
action %actions.login_action% is triggered.