2013-06-10 8 views
5

मैंने अपने उपयोगकर्ताओं को प्रबंधित करने के लिए सोनाटाउसर का उपयोग एफओएसयूसर के साथ किया और एक कस्टम कंपनी company बनाया है ताकि प्रत्येक व्यक्ति को किसी दिए गए कंपनी को संलग्न किया जा सके।सोनाटा उपयोगकर्ता - कस्टम फ़ील्ड पर सुरक्षा

user1 company1 
user2 company1 
user3 company2 
user4 company2 

उदाहरण::

अब मैं बस उन केवल उन एक ही कंपनी से जुड़ी प्रबंधित करने की क्षमता देने के लिए आवश्यकता होगी user1 सूची/संपादन में सक्षम होना चाहिए केवल user1 & user2

क्या मुझे एसीएल का उपयोग करना चाहिए?

क्या आप इस उद्देश्य के लिए सोनाटाउसर को अनुकूलित करने के लिए मुझे सही दिशा या ट्यूटोरियल पर इंगित कर सकते हैं?

उत्तर

10

हाँ एसीएल जाने का रास्ता है। VoterInterface को कार्यान्वित करने वाला एक कंपनीवॉटर बनाएं और जांचें कि क्या उपयोगकर्ता उसी वोट पर है() विधि।

कुकबुक प्रविष्टि "How to implement your own Voter to blacklist IP Addresses" एक अच्छा परिचय देता है।

अपने सर्व-निर्णय-प्रबंधक की रणनीति को 'सर्वसम्मति' में बदलें। इसका मतलब है कि अगर केवल एक मतदाता पहुंच से इनकार करता है (उदा। कंपनीवॉटर), अंतिम उपयोगकर्ता को पहुंच प्रदान नहीं की जाती है।

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

के रूप में मतदाता रजिस्टर ... अब अपनी टहनी टेम्पलेट में इसका इस्तेमाल

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

या आपके नियंत्रक में ...

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) 
{ 
    // ... 
} 
+0

मैं इस तरह की कोशिश की के बारे में स्वीकार कर लिया गया है, यह संस्करण के लिए काम करता है (अन्य कंपनियों के लिए संस्करण से बचाता है), लेकिन सूची अभी भी सभी उपयोगकर्ताओं को प्रदर्शित करता है। ऐसा लगता है कि मतदाता को लाइन प्रदर्शित करने के लिए बुलाया नहीं जाता है। –

+0

लाइन प्रदर्शित करके आपका क्या मतलब है? – nifr

+0

जैसा कि मुझे सूची ग्रिड में केवल कुछ उपयोगकर्ताओं को दिखाने की ज़रूरत है, उनके लिए कोई भी लाइन प्रदर्शित नहीं की जानी चाहिए (केवल पढ़ने के बजाय) नोट: मैं सोनाटाएडमिन ग्रिड –

1

मैं यहाँ एसीएल जरूरत नहीं थी के रूप में, (केवल मतदाताओं) मैं सोनाटा की भूमिका सुरक्षा हैंडलर का इस्तेमाल किया।

लेकिन मुझे इसका उपयोग करने में समस्याएं थीं क्योंकि isGranted() का डिफ़ॉल्ट कार्यान्वयन वर्तमान ऑब्जेक्ट को मतदाता को पास नहीं करता है।

तो मुझे इसे विस्तारित करना पड़ा, अधिक जानकारी के लिए इस github issue में मेरे एकान्तता की जांच करें।


वैसे, मेरी PR इस मुद्दे

संबंधित मुद्दे