2013-01-07 26 views
6

में भूमिका/संसाधन एसीएल को कार्यान्वित करने के लिए कैसे मैं सिमफ़ोनी 2 में एक्सेस कंट्रोल सूचियों को लागू करने के तरीके से थोड़ा विचलित हूं।सिम्फनी 2

Zend फ्रेमवर्क में (संस्करण 1 & 2), संसाधनों की एक सूची और भूमिकाओं की एक सूची परिभाषित कर रहे हैं और प्रत्येक भूमिका संसाधनों का एक सबसेट यह उपयोग करने के लिए अनुमति दी गई है असाइन किया गया है। इसलिए संसाधन और भूमिकाएं एसीएल कार्यान्वयन की मुख्य शब्दावली हैं, जो सिम्फनी 2 में नहीं है, जहां केवल भूमिकाएं शासन करती हैं।

लेगेसी एप्लिकेशन डेटाबेस में, मैं भूमिकाओं की एक सूची, संसाधनों की एक सूची और प्रत्येक भूमिका के लिए अनुमति दी संसाधनों की एक सूची को परिभाषित टेबल है (अनेक-से-अनेक संबंध)। प्रत्येक उपयोगकर्ता को एक भूमिका नियुक्त की जाती है (व्यवस्थापक, सुपर व्यवस्थापक, संपादक, और ऐसे)।

मैं एक Symfony2 आवेदन में इस डेटाबेस का उपयोग करने की जरूरत है। मेरे संसाधन इस तरह दिखेगा: ARTICLE_EDIT, ARTICLE_WRITE, COMMENT_EDIT, आदि

Symfony में मेरे User इकाई Symfony\Component\Security\Core\User\UserInterface इंटरफ़ेस लागू करता है और इसलिए एक getRoles) विधि है।

मैं अनुमति संसाधनों को परिभाषित करने, जिसका मतलब है मैं संसाधनों के रूप में भूमिकाओं (मेरा मतलब है कि Zend फ्रेमवर्क में क्या कहते हैं संसाधन भूमिकाओं यहाँ कहा जाता है) का उपयोग इस विधि का उपयोग करना चाहते हैं।

क्या आप पुष्टि करते हैं कि मुझे इस विधि का उपयोग करना चाहिए?

इसका मतलब यह है कि मैं प्रत्येक उपयोगकर्ता की भूमिका (व्यवस्थापक, संपादक, ...) के बारे में अब और कोई परवाह नहीं है, लेकिन केवल अपने संसाधनों के बारे में।

मैं अपने नियंत्रकों में $this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE') का उपयोग करूंगा।

इस यह करने के लिए सही रास्ता है और यह Symfony में भूमिकाओं का उपयोग करने के लिए एक धोखा तरीका नहीं हो सकता है?

उत्तर

2

बाद में इस सवाल का जवाब देने के लिए वर्ष, इसे हल करने में बहुत आसान था।

समाधान भूमिकाओं और संसाधनों के विचारों को मिश्रण करना है।

मान लें कि role तालिका, resource तालिका और role_resource कई संबंधों के लिए कई परिभाषित किए गए हैं।

उपयोगकर्ताओं को एक user तालिका में जमा हो जाती है।

यहाँ इसी सिद्धांत संस्थाओं हैं:

उपयोगकर्ता:

use Symfony\Component\Security\Core\User\UserInterface; 

class User implements UserInterface 
{ 
    /** 
    * @Id @Column(type="integer") 
    * @GeneratedValue 
    */ 
    private $id; 

    /** 
    * @ManyToOne(targetEntity="Role") 
    * @JoinColumn(name="role_id", referencedColumnName="id") 
    **/ 
    private $role; 

    // ... 
} 

भूमिका:

class Role 
{ 
    /** 
    * @Id @Column(type="integer") 
    * @GeneratedValue 
    */ 
    private $id; 

    /** @Column(type="string") */ 
    private $name; 

    /** 
    * @ManyToMany(targetEntity="Resource") 
    * @JoinTable(name="role_resource", 
    *  joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@JoinColumn(name="resource_id", referencedColumnName="id")} 
    *  ) 
    **/ 
    private $resources; 

    // ... 
} 

संसाधन:

class Resource 
{ 
    /** 
    * @Id @Column(type="integer") 
    * @GeneratedValue 
    */ 
    private $id; 

    /** @Column(type="string") */ 
    private $name; 

    // ... 
} 

तो अब समाधान लागू करने के लिए हैUserInterface की getRoles इस तरह से:

use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\Role\Role; 

class User implements UserInterface 
{ 
    // ... 

    /** 
    * @var Role[] 
    **/ 
    private $roles; 

    /** 
    * {@inheritDoc} 
    */ 
    public function getRoles() 
    { 
     if (isset($this->roles)) { 
      return $this->roles; 
     } 

     $this->roles = array(); 

     $userRole = $this->getRole(); 

     $resources = $userRole->getResources(); 

     foreach ($resources as $resource) { 
      $this->roles[] = new Role('ROLE_' . $resource); 
     } 

     return $this->roles; 
    } 

} 

इस तरह, वर्तमान उपयोगकर्ता के लिए जिम्मेदार ठहराया संसाधनों इस तरह से जाँच की जा सकती (पर विचार के लिए एक संसाधन है जिसका नाम ARTICLE_WRITE है वहाँ):

$this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE') 
0

मुझे लगता है कि यह आपके प्रश्न का उत्तर देगा।

http://symfony.com/doc/current/cookbook/security/acl.html http://symfony.com/doc/current/cookbook/security/acl_advanced.html

$builder = new MaskBuilder(); 
$builder 
->add('view') 
->add('edit') 
->add('delete') 
->add('undelete'); 
$mask = $builder->get(); // int(29) 

$identity = new UserSecurityIdentity('johannes', 'Acme\UserBundle\Entity\User'); 
$acl->insertObjectAce($identity, $mask);