symfony - Symfony2: creating a new SecurityIdentity -
i'm using acl in symfony 2.1, , need create new securityidentity, acl can set in function of sort of groups.
picture following situation: there groups users (with different roles) each have user information. in group 1, users role_admin can't edit other users same group's information, in group 2, users role_admin can edit others information.
so acl vary in function of group user in.
i thought i'd start solving problem creation of new "groupsecurityidentity". class doesn't suffice, exception when use it:
$sid must either instance of usersecurityidentity, or rolesecurityidentity.
my question is: how "register" new securityidentity can use rolesecurityidentity , usersecurityidentity?
what better ways there implement system similar want do?
2 years ago went down path, turned out bad decision. modifying acl system difficult , might cause problems when updating symfony. there @ least 2 better solutions. i'll list them can decide best suits needs.
new security identity
i'm using groupinterface
fosuserbundle, guess use own too. following files need added:
-
the method change private - whole file has copied, change has made
hydrateobjectidentities
-
we have duplicate whole file must extend
aclprovider
, we're using custom 1 , can't therefore extend stockmutableaclprovider
. methods changedgetinsertsecurityidentitysql
,getselectsecurityidentityidsql
.
next up: rewire dependency injection container providing following parameters:
<parameter key="security.acl.dbal.provider.class"> acme\bundle\demobundle\security\acl\dbal\mutableaclprovider </parameter> <parameter key="security.acl.security_identity_retrieval_strategy.class"> acme\bundle\demobundle\security\acl\domain\securityidentityretrievalstrategy </parameter>
time cross fingers , see whether works. since old code might have forgotten something.
use roles groups
the idea have group names correspond roles.
a simple way have user
entity re-implement userinterface::getroles
:
public function getroles() { $roles = parent::getroles(); // can cached should there performance issues // highly doubt there be. foreach ($this->getgroups() $group) { // groupinterface::getrole() have use // canonical name `role_group_name_of_group` $roles[] = $group->getrole(); } return $roles; }
a possible implementation of groupinterface::getrole()
:
public function getrole() { $name = $this->getnamecanonical(); return 'role_group_'.mb_convert_case($name, mb_case_upper, 'utf-8'); }
it's matter of creating required ace-s written in cookbook article.
create voter
finally, use custom voters check presence of specific groups , whether user has access said object. possible implementation:
<?php namespace acme\bundle\demobundle\authorization\voter; use symfony\component\security\core\authentication\token\tokeninterface; use symfony\component\security\core\authorization\voter\voterinterface; class mysecureobjectvoter implements voterinterface { /** * {@inheritdoc} */ public function supportsattribute($attribute) { $supported = array('view'); return in_array($attribute, $supported); } /** * {@inheritdoc} */ public function supportsclass($class) { return $class instanceof groupableinterface; } /** * {@inheritdoc} */ public function vote(tokeninterface $token, $object, array $attributes) { $result = voterinterface::access_abstain; if (!$object instanceof mysecureobject) { return voterinterface::access_abstain; } foreach ($attributes $attribute) { if (!$this->supportsattribute($attribute)) { continue; } // access granted, if user , object have @ least 1 // group in common. if ('view' === $attribute) { $objgroups = $object->getgroups(); $usergroups = $token->getuser()->getgroups(); foreach ($usergroups $usergroup) { foreach ($objgroups $objgroup) { if ($usergroup->equals($objgroup)) { return voterinterface::access_granted; } } } return voterinterface::access_denied; } } } }
for more details on voters please refer cookbook example.
i avoid creating custom security identity. use 2 other methods provided. second solution works best, if having lots of records , each of them must have different access settings. voters used setting simple access granting logic (which smaller systems seem fall under) or when flexibility necessary.
Comments
Post a Comment