Có ACL là con đường để đi. tạo một CompanyVoter thực hiện VoterInterface và kiểm tra xem người dùng có ở cùng một công ty bên trong phương thức vote() của nó hay không.
mục nhập sổ nấu ăn "How to implement your own Voter to blacklist IP Addresses" cung cấp phần giới thiệu tốt.
thay đổi chiến lược của người quản lý quyết định quyền truy cập của bạn thành 'nhất trí'. Điều này có nghĩa là nếu chỉ có một cử tri từ chối quyền truy cập (ví dụ: CompanyVoter), quyền truy cập không được cấp cho người dùng cuối.
# app/config/security.yml
security:
access_decision_manager:
strategy: unanimous
Bây giờ tạo Cử Tri của bạn
// src/Acme/AcmeBundle/YourBundle/Security/Authorization/Voter/CompanyVoter.php
namespace Acme\YourBundle\Security\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Acme\YourUserBundleBundle\Entity\User;
use Symfony\Component\Security\Core\User\UserInterface;
class CompanyVoter implements VoterInterface
{
private $container;
public function __construct($container)
{
$this->container = $container;
}
public function supportsAttribute($attribute)
{
return in_array($attribute, array(
'EDIT',
'ACTIVATE',
// ...
));
}
public function supportsClass($class)
{
return in_array("FOS\UserBundle\Model\UserInterface", class_implements($class));
}
public function vote(TokenInterface $token, $object, array $attributes)
{
if (!($this->supportsClass(get_class($object)))) {
return VoterInterface::ACCESS_ABSTAIN;
}
foreach ($attributes as $attribute) {
if (!$this->supportsAttribute($attribute)) {
return VoterInterface::ACCESS_ABSTAIN;
}
}
$user = $token->getUser();
if (!($user instanceof UserInterface)) {
return VoterInterface::ACCESS_DENIED;
}
// check if the user has the same company
if ($user->getCompany() == $object->getCompany()) {
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
}
}
Cuối cùng đăng ký cử tri như như một dịch vụ
# src/Acme/AcmeBundle/Resources/config/services.yml
services:
security.access.company_voter:
class: Acme\YourBundle\Security\Authorization\Voter\CompanyVoter
public: false
tags:
- { name: security.voter }
... bây giờ sử dụng nó trong mẫu cành lá của bạn
{% if is_granted('EDIT', user) %}<a href="#">Edit</a>{% endif %}
{% if is_granted('ACTIVATE', user) %}<a href="#">activate</a>{% endif %}
hoặc trong bộ điều khiển của bạn ...
public function editAction(UserInterface $user)
{
if ($this->get('security.context')->isGranted('EDIT',$user)) {
throw new \Symfony\ComponentSecurity\Core\Exception\AccessDeniedException();
}
}
hoặc sử dụng JMSSecurityExtraBundle ...
/**
* @SecureParam(name="user", permissions="EDIT")
*/
public function editUser(UserInterface $user)
{
// ...
}
tôi đã cố gắng theo cách này, nó hoạt động cho phiên bản (ngăn chặn phiên bản cho các công ty khác) nhưng danh sách này vẫn hiển thị tất cả những người sử dụng. Có vẻ như cử tri không được gọi để hiển thị dòng. –
ý của bạn là gì khi hiển thị dòng? – nifr
Vì tôi cần chỉ hiển thị một số người dùng trong lưới danh sách, nên không có dòng nào hiển thị cho họ (thay vì xuất hiện chỉ đọc) Lưu ý: Tôi đang nói về lưới SonataAdmin –