2016-01-13 9 views
5

Ho un'API di base che autentica gli utenti utilizzando FOSOAuthServerBundle. Gli utenti possono avere ruoli ROLE_USER e ROLE_ADMIN. Sulla base dei documenti FOSOAuthServerBundle, il comportamento predefinito consiste nell'utilizzare gli ambiti come ruoli, quindi ho pensato che quando ho un utente regolare, il pacchetto restituisce scope: user nella risposta e, quando è un utente amministratore, restituisce scope: admin. Ma non funziona così. Il pacchetto restituisce tutto ciò che è configurato nella voce supported_scopes. Di seguito è il mio config.yml.Come gestire gli ambiti ROLES e FOSOAuthServerBundle

fos_oauth_server: 
    service: 
     options: 
      supported_scopes: user admin 

sezione My access_control in security.yml è vuoto, e la mia sezione firewalls è qui sotto:

firewalls: 
     users_create: 
      pattern: ^/v1/users 
      methods: [POST] 
      security: false 

     api: 
      pattern: ^/ 
      security: true 
      fos_oauth: true 
      stateless: true 

access_control: 
     # You can omit this if /api can be accessed both authenticated and anonymously 

In questo modo il fascio di tornare sempre user admin come campo di applicazione, anche se l'utente non ha il ruolo ROLE_ADMIN.

{ 
"access_token": "ZGQ2ODE5ZjAzNTZkOWY0OWMyNmZmODE4MjcwZTJmYjExNzY0NzQxOTRmMzk4NzA2Mjc2NjIyZmY1ZDgwMzk4NA" 
"expires_in": 3600 
"token_type": "bearer" 
"scope": "user admin" 
"refresh_token": "NmM5ZGFmNzBiNTNjYmQzMTQ1MTk0ODJjOTAxMWU0YWIwMzM1MzgyODg4ZTAzNTI5ZTk2MDc3OGU2MTg0MWZiMA" 
} 

Cosa mi manca? Il ruolo utente non è associato all'ambito token? C'è un modo migliore per sapere se il mio utente è un amministratore o no?

+0

Forse non è il tuo 'security.yml' ed è incollato da' config.yml'? Potresti fornire la sezione 'access_control:' da te 'security.yml'? –

+0

Hai ragione Illya. Modifica la mia domanda. –

risposta

2

Da doc, il comportamento predefinito consiste nel mappare gli ambiti con i ruoli. Nel tuo caso, i ruoli sarebbero ROLE_USER e ROLE_ADMIN.

Ora per limitare l'utilizzo, devi modificare il file security.yml un po 'come questo:

# app/config/security.yml 
security: 
    access_control: 
     - { path: ^/api/super/secured, role: ROLE_ADMIN } 
     - { path: ^/api/general, role: ROLE_USER } 

Per limitare l'accesso all'interno del controller, è possibile utilizzare questo:

if ($this->get('security.context')->isGranted('ROLE_ADMIN')) { 
    // the user has the ROLE_ADMIN role, so act accordingly 
} 

Anche in questo caso dal doc,

Ora i client potranno passare un parametro di ambito quando richiedono un token di accesso.

Spero che questo aiuti.

UPDATE:

Guardate questa risposta here a una domanda simile e questo article sull'impostazione FOSOAuthServerBundle. Prestare particolare attenzione alla parte di configurazione.

+0

Ma come posso sapere nel mio frontend se il mio utente è un amministratore o no? –

+0

In template Twig si può fare questo: '{% se is_granted ('ROLE_ADMIN')%} {# po 'di testo #} {% endif%}' o implementare un metodo isGranted nella tua entità utente (http://stackoverflow.com/questions/9080530/get-role-of-a-user-not-logged-in-twig-symfony2) – Delphine

+0

Delphine, non hai capito il mio punto. Io uso un Api REST e richiesta dati dal mio frontend javascript. Devo fare una richiesta API e poi ottenere qual è il mio ruolo utente. Questi dati non vengono quando faccio/me richiesta. Quando richiediamo il token dell'API, il ritorno (come menzionato sopra) viene fornito con un parametro "scope". Ma non so se è la strada giusta e sembra che non funzioni. –

1

FOSOAuthServerBundle autentica il tuo utente, in base al token, quindi non devi preoccuparti degli ambiti, è una cosa diversa dai ruoli. All'interno del controller è possibile ottenere $this->getUser() per ottenere l'utente autenticato corrente. Se funziona, controllare se funziona anche isGranted.

http://symfony.com/doc/current/book/security.html

public function helloAction($name) 
{ 
    // The second parameter is used to specify on what object the role is tested. 
    $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!'); 

    // Old way : 
    // if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) { 
    //  throw $this->createAccessDeniedException('Unable to access this page!'); 
    // } 

    // ... 
} 

In caso di $this->getUser() non funziona si dovrà impostare fetch al EAGER sull'entità AccessToken.

class AccessToken extends BaseAccessToken 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Client") 
    * @ORM\JoinColumn(nullable=false) 
    */ 
    protected $client; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", fetch="EAGER") 
    */ 
    protected $user; 
} 
+0

Non hai capito il mio punto. Ho bisogno di un modo per sapere qual è il ruolo dell'utente nel mio frontend. Quindi, quando richiedo il token ho bisogno di sapere anche in quali ruoli è stato concesso all'utente. Abbiamo già il parametro 'scope' nel token, ma sembra che non funzioni come previsto (ho messo un esempio sopra). –

+0

non puoi semplicemente ottenere i dati utente correnti da API? – Vardius

+0

No ... quando si richiedono i dettagli dell'utente FOSOAuthServerBundle non restituisce ambiti o regole. Se presti attenzione alla mia domanda, vedrai che la richiesta/token ti fornisce gli ambiti, ma non funziona. –