奏鸣曲用户-自定义字段上的安全性 [英] Sonata User - Security on custom field

查看:56
本文介绍了奏鸣曲用户-自定义字段上的安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用SonataUser和FOSUser来管理我的用户,并创建了一个自定义字段company,将每个字段附加到给定的公司.

I used SonataUser with FOSUser to manage my users and created a custom field company to attach each one to a given company.

现在,我只需要给用户提供仅管理隶属于同一公司的用户的功能:

Now I'd simply need to give users the ability to manage only users attached to the same company:

user1 company1
user2 company1
user3 company2
user4 company2

示例:user1应该只能列出/编辑user1& user2

Example: user1 should be able to list/edit only user1 & user2

我应该使用ACL吗?

您能为此指出正确的方向或教程来自定义SonataUser吗?

Can you point me to the right direction or tutorial to customize SonataUser for this purpose ?

推荐答案

是的,ACL是必经之路.创建一个实现VoterInterface的CompanyVoter,并检查用户的vote()方法中用户是否在同一家公司中.

Yes ACL is the way to go. create a CompanyVoter implementing VoterInterface and check if the user is on the same company inside it's vote() method.

食谱条目"如何实施自己的选民将IP地址列入黑名单"作了很好的介绍.

the cookbook entry "How to implement your own Voter to blacklist IP Addresses" gives a good introduction.

将您的访问决策经理的策略更改为一致".这意味着,如果只有一个投票者拒绝访问(例如CompanyVoter),则不会将访问权限授予最终用户.

change your access-decision-manager's strategy to 'unanimous'. This means if only one voter denies access (e.g. the CompanyVoter), access is not granted to the end user.

# app/config/security.yml
security:
    access_decision_manager:
        strategy: unanimous

现在创建您的选民

// 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;
   }

}

最后将选民注册为服务

# 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 }

...现在在您的树枝模板中使用它

... now use it in your twig template

{% if is_granted('EDIT', user) %}<a href="#">Edit</a>{% endif %}
{% if is_granted('ACTIVATE', user) %}<a href="#">activate</a>{% endif %}

或在您的控制器中...

or in your controller ...

public function editAction(UserInterface $user)
{
    if ( $this->get('security.context')->isGranted('EDIT',$user) ) {
        throw new \Symfony\ComponentSecurity\Core\Exception\AccessDeniedException();
    }
}

或使用 JMSSecurityExtraBundle ...

/**
 * @SecureParam(name="user", permissions="EDIT")
 */
public function editUser(UserInterface $user) 
{  
    // ...
}

这篇关于奏鸣曲用户-自定义字段上的安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆