Table of Contents
Questions & Feedback
Found a typo or an error?
Want to improve this document? Edit it.
Need support or have a technical question?
Post to the user mailing-list.
Master Symfony2 fundamentals
Symfony hosting done right
Discover the SensioLabs Support
Proteggere servizi e metodi di un'applicazione
Proteggere servizi e metodi di un'applicazione¶
Nel capitolo sulla sicurezza, si può vedere come
proteggere un controllore, richiedendo il
servizio security.context dal contenitore di servizi e verificando il ruolo dell'utente attuale:
1 2 3 4 5 6 7 8 9 10 11 | // ...
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
public function helloAction($name)
{
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}
// ...
}
|
Si può anche proteggere qualsiasi servizio in modo simile, iniettando in esso
il servizio security.context. Per un'introduzione generale all'iniezione di dipendenze
nei servizi, vedere il capitolo Contenitore di servizi del libro. Per esempio,
si supponga di avere una classe NewsletterManager, che invia email, e di voler
restringere il suo utilizzo ai soli utenti con un ruolo ROLE_NEWSLETTER_ADMIN.
Prima di aggiungere la sicurezza, la classe assomiglia a qualcosa del genere:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // src/Acme/HelloBundle/Newsletter/NewsletterManager.php
namespace Acme\HelloBundle\Newsletter;
class NewsletterManager
{
public function sendNewsletter()
{
// qui va la logica specifica
}
// ...
}
|
Lo scopo è verificare il ruolo dell'utente al richiamo del metodo sendNewsletter().
Il primo passo in questa direzione è l'iniezione del servizio security.context
nell'oggetto. Non avendo molto senso non eseguire un controllo di sicurezza, questo è
un candidato ideale per un'iniezione nel costruttore, che garantisce che l'oggetto
della sicurezza sia disponibile in tutta la classe
NewsletterManager:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | namespace Acme\HelloBundle\Newsletter;
use Symfony\Component\Security\Core\SecurityContextInterface;
class NewsletterManager
{
protected $securityContext;
public function __construct(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
// ...
}
|
Quindi, nella configurazione dei servizi, si può iniettare il servizio:
- YAML
# src/Acme/HelloBundle/Resources/config/services.yml parameters: newsletter_manager.class: Acme\HelloBundle\Newsletter\NewsletterManager services: newsletter_manager: class: "%newsletter_manager.class%" arguments: [@security.context] - XML
1 2 3 4 5 6 7 8 9 10
<!-- src/Acme/HelloBundle/Resources/config/services.xml --> <parameters> <parameter key="newsletter_manager.class">Acme\HelloBundle\Newsletter\NewsletterManager</parameter> </parameters> <services> <service id="newsletter_manager" class="%newsletter_manager.class%"> <argument type="service" id="security.context"/> </service> </services>
- PHP
1 2 3 4 5 6 7 8 9 10
// src/Acme/HelloBundle/Resources/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; $container->setParameter('newsletter_manager.class', 'Acme\HelloBundle\Newsletter\NewsletterManager'); $container->setDefinition('newsletter_manager', new Definition( '%newsletter_manager.class%', array(new Reference('security.context')) ));
Il servizio iniettato può quindi essere usato per eseguire il controllo di sicurezza,
quando il metodo sendNewsletter() viene richiamato:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | namespace Acme\HelloBundle\Newsletter;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\SecurityContextInterface;
// ...
class NewsletterManager
{
protected $securityContext;
public function __construct(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
public function sendNewsletter()
{
if (false === $this->securityContext->isGranted('ROLE_NEWSLETTER_ADMIN')) {
throw new AccessDeniedException();
}
//--
}
// ...
}
|
Se l'utente attuale non ha il ruolo ROLE_NEWSLETTER_ADMIN, gli sarà richiesto
di autenticarsi.
Mettere i sicurezza i metodi con le annotazioni¶
Si possono anche proteggere i metodi di un servizio tramite annotazioni, usando il bundle JMSSecurityExtraBundle. Questo bundle è incluso nella Standard Edition di Symfony2.
Per abilitare le annotazioni, assegnare il tag
security.secure_service al servizio da proteggere
(si può anche abilitare automaticamente la funzionalità per tutti i servizi, vedere i
dettagli più avanti):
- YAML
1 2 3 4 5 6 7 8
# src/Acme/HelloBundle/Resources/config/services.yml # ... services: newsletter_manager: # ... tags: - { name: security.secure_service }
- XML
1 2 3 4 5 6 7 8 9
<!-- src/Acme/HelloBundle/Resources/config/services.xml --> <!-- ... --> <services> <service id="newsletter_manager" class="%newsletter_manager.class%"> <!-- ... --> <tag name="security.secure_service" /> </service> </services>
- PHP
1 2 3 4 5 6 7 8 9 10
// src/Acme/HelloBundle/Resources/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; $definition = new Definition( '%newsletter_manager.class%', array(new Reference('security.context')) )); $definition->addTag('security.secure_service'); $container->setDefinition('newsletter_manager', $definition);
Si possono ottenere gli stessi risultati usando le annotazioni:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | namespace Acme\HelloBundle\Newsletter;
use JMS\SecurityExtraBundle\Annotation\Secure;
// ...
class NewsletterManager
{
/**
* @Secure(roles="ROLE_NEWSLETTER_ADMIN")
*/
public function sendNewsletter()
{
// ...
}
// ...
}
|
Note
Le annotazioni funzionano perché viene creata una classe proxy per la propria classe, che esegue i controlli di sicurezza. Questo vuol dire che, sebbene si possano usare le annotazioni su metodi pubblici e protetti, non si possono usare su metodi privati o su metodi finali.
Il bundle JMSSecurityExtraBundle consente anche di proteggere i parametri e
i valori resituiti dai metodi. Per maggiori informazioni vedere la documentazione di
JMSSecurityExtraBundle.





is a trademark of Fabien Potencier. All rights reserved.