Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with ROLES and FOSOAuthServerBundle scopes

I have a basic api that authenticates users using FOSOAuthServerBundle. Users can have ROLE_USER and ROLE_ADMIN roles. Based on FOSOAuthServerBundle docs, the default behavior is to use scopes as roles, so I've thought that when I have a regular user, the bundle would return scope: userin the response, and when it's a admin user, would return scope: admin. But it's not working like this. The bundle is returning whatever is configured in the supported_scopesentry. Below is my config.yml.

fos_oauth_server:
    service:
        options:
            supported_scopes: user admin

My access_control section in security.yml is empty, and my firewalls section is below:

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

This way the bundle always return user admin as scope, even if the user does not have the ROLE_ADMIN role.

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

What I'm I missing? Isn't the user role attached to token scope? Is there any better way to know if my user is an admin or not?

like image 966
Hugo Nogueira Avatar asked Sep 25 '22 16:09

Hugo Nogueira


3 Answers

From the doc, the default behaviour is to map scopes with roles. In your case, the roles would be ROLE_USER and ROLE_ADMIN.

Now to restrict usage, you'd edit your security.yml file somewhat like this:

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

To restrict access inside controller, you can use this:

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

Again from the doc,

Now, clients will be able to pass a scope parameter when they request an access token.

Hope this helps.

UPDATE:

Look at this answer here to a similar question and this article on setting up FOSOAuthServerBundle . Pay close attention to the configuration part.

like image 110
mansoor.khan Avatar answered Nov 10 '22 01:11

mansoor.khan


FOSOAuthServerBundle authenticate your user, based on token, so you dont have to worry about scopes, it is a different thing then roles. Inside your controller you can get $this->getUser() to get the current authenticated user. If this works then checking if isGranted works as well.

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 case of $this->getUser() doesnt work you will have to set fetch to EAGER on the AccessToken entity.

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;
}
like image 25
vardius Avatar answered Nov 09 '22 23:11

vardius


There is an issue on github that dates back to 2013 for this. If you read that issue and follow the links you will eventually end up with the user Spomky creating his own library and Symfony bundle and being suggested as a maintainer of the FOSAuthServerBundle. It appears the FOS organisation will merge Spomky's work into the next major version of FOSOAuthServerBundle once it is stable.

like image 28
bblue Avatar answered Nov 10 '22 00:11

bblue