Как работать с областями ROLES и FOSOAuthServerBundle

У меня есть базовый API, который аутентифицирует пользователей с помощью FOSOAuthServerBundle. Пользователи могут иметь роли ROLE_USER и ROLE_ADMIN. Основываясь на документах FOSOAuthServerBundle, поведение по умолчанию заключается в использовании областей в качестве ролей, поэтому я подумал, что когда у меня есть обычный пользователь, пакет вернется scope: userв ответе, и когда это пользователь с правами администратора, вернется scope: admin, Но это не работает так. Пакет возвращает все, что настроено в supported_scopesзапись. Ниже мой config.yml,

fos_oauth_server:
service:
options:
supported_scopes: user admin

мой access_control раздел в security.yml пусто, а мой firewalls раздел ниже:

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

Таким образом, пакет всегда возвращается user admin в качестве области действия, даже если у пользователя нет роли ROLE_ADMIN.

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

Что мне не хватает? Разве роль пользователя не привязана к области действия токена? Есть ли лучший способ узнать, является ли мой пользователь администратором или нет?

5

Решение

От доктор, поведение по умолчанию — сопоставление областей с ролями. В вашем случае роли будут ROLE_USER и ROLE_ADMIN.

Теперь, чтобы ограничить использование, вы должны отредактировать файл security.yml примерно так:

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

Чтобы ограничить доступ внутри контроллера, вы можете использовать это:

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

Опять из доктор,

Теперь клиенты смогут передавать параметр области, когда они запрашивают
токен доступа.

Надеюсь это поможет.

ОБНОВИТЬ:

Посмотри на этот ответ Вот на аналогичный вопрос, и это статья по настройке FOSOAuthServerBundle. Обратите особое внимание на конфигурационную часть.

2

Другие решения

FOSOAuthServerBundle аутентифицируйте своего пользователя, основываясь на токене, так что вам не нужно беспокоиться о границах, это другое, чем роли. Внутри вашего контроллера вы можете получить $this->getUser() получить текущего аутентифицированного пользователя. Если это работает, тогда проверяем, 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!');
// }

// ...
}

В случае $this->getUser() не работает, вам придется установить fetch в EAGER на 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;
}
1

Есть проблема на GitHub, который даты вернуться к 2013 году для этого. Если вы прочитаете эту проблему и перейдете по ссылкам, вы в конечном итоге создадите пользователя Spomky. его собственная библиотека и пакет Symfony и быть предлагается в качестве сопровождающего FOSAuthServerBundle. Похоже, что организация FOS объединит работу Spomky со следующей основной версией FOSOAuthServerBundle, как только она станет стабильной.

1

Вы можете вернуть информацию об учетной записи пользователя вместе с токеном.

Вот мой подход к аналогичной ситуации: я создал прокси-маршрут, который принимает имя пользователя и пароль в качестве параметров запроса, добавляет в запрос информацию о клиенте oauth и перенаправляет запрос в действие Oauth Token. Затем я беру эту информацию и возвращаю информацию о пользователе вместе с токеном.

/**
* @REST\Post("/authorize")
*/
public function loginAction(Request $request){
$request->request->add( array(
'grant_type' => 'password',
'client_id' => $this->container->getParameter('oauth_client_id') . "_" . $this->container->getParameter('oauth_client_random_id'),
'client_secret' => $this->container->getParameter('oauth_client_secret')
));
$tokenAction = $this->get('fos_oauth_server.controller.token')->tokenAction($request);
$tokenObject = json_decode( $tokenAction->getContent() );

if(key_exists('error_description', $tokenObject)){
return $this->view(["error" => $tokenObject->error_description], 401);
};$user = $this->getDoctrine()->getRepository('\App\Entity\Oauth\AccessToken')->findOneBy( array('token' => $tokenObject->access_token ) )->getUser();
$return = array(
"roles" => $user->getUser()->getRoles(),
"access_token" => $tokenObject->access_token,
"expires_in" => $tokenObject->expires_in,
"token_type" => $tokenObject->token_type,
"scope" =>$tokenObject->scope,
"refresh_token" => $tokenObject->refresh_token
);
return $this->view($return);
}

Я использую этот маршрут для аутентификации / генерации токенов, а не по маршруту, который идет с OAuthBundle

0
По вопросам рекламы [email protected]