2013-06-13 12 views
6

Chcę użyć wyborcy, aby zezwolić właścicielom tylko na edycję obiektu projektu w mojej aplikacji.Jak zapewnić bezpieczeństwo wyborcy dostęp do bieżącego obiektu?

Mam trasę/projekt/42/edycja, która wywołuje moje działanie ProjectController.editAction (Project $ project). Używam podpowiedzi typu (projekt Project $), aby automatycznie wywoływać ParamConverter w celu przekonwertowania ID 42 z URI do obiektu projektu. Działa to ładnie dla działania kontrolera, jednak wydaje się, że jest on zbyt późno przywoływany przez wyborcę. Jego metoda vote() zostaje wywołana wraz z żądaniem jako drugi parametr, a nie mój projekt.

Czy istnieje sposób przekazania projektu wyborcy bez konieczności ponownego pobierania go z bazy danych?

AKTUALIZACJA: I learned, które muszę ręcznie wywołać isGranted() na kontekście zabezpieczeń w metodzie edycji. Jest to bardzo podobne podejście do this answer.

Oto moja Wyborca:

namespace FUxCon2013\ProjectsBundle\Security; 

use FUxCon2013\ProjectsBundle\Entity\Project; 
use Symfony\Component\BrowserKit\Request; 
use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 

class OwnerVoter implements VoterInterface 
{ 
    public function __construct(ContainerInterface $container) 
    { 
     $this->container  = $container; 
    } 

    public function supportsAttribute($attribute) 
    { 
     return $attribute == 'MAY_EDIT'; 
    } 

    public function supportsClass($class) 
    { 
     // your voter supports all type of token classes, so return true 
     return true; 
    } 

    function vote(TokenInterface $token, $object, array $attributes) 
    { 
     if (!in_array('MAY_EDIT', $attributes)) { 
      return self::ACCESS_ABSTAIN; 
     } 
     if (!($object instanceof Project)) { 
      return self::ACCESS_ABSTAIN; 
     } 

     $user = $token->getUser(); 
     $securityContext = $this->container->get('security.context'); 

     return $securityContext->isGranted('IS_AUTHENTICATED_FULLY') 
      && $user->getId() == $object->getUser()->getId() 
      ? self::ACCESS_GRANTED 
      : self::ACCESS_DENIED; 
    } 
} 

zarejestrować to w configure.yml tak, że dostaje pojemnik usług jako parametru:

services: 
    fuxcon2013.security.owner_voter: 
     class:  FUxCon2013\ProjectsBundle\Security\OwnerVoter 
     public:  false 
     arguments: [ @service_container ] 
     tags: 
      - { name: security.voter } 

Ostatni blok jest skonfigurowanie menedżera decyzji dostęp w security.yml do jednogłośnego:

security: 
    access_decision_manager: 
     # strategy can be: affirmative, unanimous or consensus 
     strategy: unanimous 
     allow_if_all_abstain: true 
+0

Czy możesz podać kod swojego wyborcy? nie rozumiem części [...] bez konieczności jej ponownego pobierania z bazy ** **. – nifr

Odpowiedz

1

Proszę spojrzeć na this answer napisałem wczoraj.

Możesz łatwo dostosować to do swoich potrzeb, sprawdzając właściciela obiektu.

0

Bieżący obiekt nie zostanie przekazany wyborcy, jeśli użyje się procedury obsługi zabezpieczeń roli.

Musiałem extend the latter, aby uzyskać pierwsze.

Nie wahaj się komentować po szczegóły.

Powiązane problemy