Как ограничить доступ действия / метода (Контроллера) для конкретного пользователя в Symfony?

Есть ли способ ограничить доступ к определенным маршрутам, иначе действие / метод контроллера в Symfony на основе пользователя?

Я реализую FOSUserBundle для управления пользователями, и у него есть роли для определения разрешений, которые хорошо работают, если у меня есть пользователь с определенными ролями, но если я хочу ограничить страницу на основе пользователей, мне нужно создать роль для каждого маршрута или есть какой-то лучший подход.

Я посмотрел в ACL и его идеально подходит, но я не могу найти решение для моего дела, или я что-то там упустил.

Нужны помощь и идеи.

Обновления

@ AJ Cerqueti — Ответ может быть быстро исправлен, но я ищу лучший подход, если таковой имеется.

Чтобы быть более конкретным, можно назначить пользователю права доступа для маршрутов, используя ACL или какой-то другой более подходящий подход.

1

Решение

SYMFONY> = 2.6

Symfony <= 2.5

Для простых нужд, как это вы можете создать охранного избирателя которые точно соответствуют вашим потребностям (списки ACL обычно используются для сложных задач, в том числе из-за непростой реализации).

Затем вы можете использовать избирателя в вашем контроллере, как описано в документации:

// get a Post instance
$post = ...;

// keep in mind, this will call all registered security voters
if (false === $this->get('security.authorization_checker')->isGranted('view', $post)) {
throw new AccessDeniedException('Unauthorised access!');
}

Читайте также Как использовать избирателей для проверки прав пользователей

ОБНОВЛЕНИЕ НА ОСНОВЕ КОММЕНТАРИИ:

Возможно, будет лучше узнать, на скольких маршрутах вы хотите добавить это поведение, но в любом случае (и если вы хотите избежать добавления в каждый контроллер кода @AJCerqueti), вы можете использовать Voter, как в этом простом примере:

Класс избирателя:

// src/AppBundle/Security/Authorization/Voter/RouteVoter.php
namespace AppBundle\Security\Authorization\Voter;

use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class RouteVoter implements VoterInterface
{
private   $routes;

public function __construct(array $routes = array())
{
$this->routes        = $routes;
}

public function supportsAttribute($attribute)
{
// you won't check against a user attribute, so return true
return true;
}

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

public function vote(TokenInterface $token, $object, array $attributes)
{
// get get allowed routes from current logged in user
$userRoutes = $token->getUser()->getRoutes();

// implement as you want the checks and return the related voter constant as below

if (...) {# your implementation

return VoterInterface::ACCESS_DENIED;
}

return VoterInterface::ACCESS_ABSTAIN;
}
}

Зарегистрировать избирателя:

<service id="security.access.route_voter"class="AppBundle\Security\Authorization\Voter\RouteVoter" public="false">
<argument type="collection">
<argument>route_one</argument>
<argument>route_two</argument>
</argument>
<tag name="security.voter" />

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

Может ли это соответствовать вашим потребностям?

2

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

Согласитесь с предыдущими ответами о том, что списки ACL, избиратели или какое-либо решение на основе ролей определенно является подходом наилучшей практики, но для этого дополнительного случая предложило бы расширить FOSUser, добавив поле ‘slug’, и затем проверить это:

if('accessible_slug' !== $this->get('security.context')->getToken()->getUser()->getSlug()) {
throw new AccessDeniedException()
}

Это означает, что нужно настроить слаг для групп контроллеров / действий и настроить их для пользователя. Подобно ролям, но без лишних накладных расходов. Все еще предпочитают Избирателей и какую-то иерархию ролей, но надеюсь, что это поможет.

2

Ты можешь использовать AccessDeniedException Symfony2

use Symfony\Component\Security\Core\Exception\AccessDeniedException;

Затем проверьте, залогинен ли пользователь,

if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
} else {
Continue;
}
1

В app/config/security.yml есть раздел access_control:, Там вы можете определить ограничения доступа для конкретных путей, например.
- { path: ^/faq/admin, roles: ROLE_FAQ_ADMIN }

path Аргумент является регулярным выражением, поэтому приведенная выше запись ограничит доступ к любому пути, начинающемуся с /faq/adminнапример /faq/admin/show-something, /faq/admin/show-something-else и т.д. Только пользователи с указанной ролью будут иметь доступ к этим путям. Для других пользователей AccessDeniedException будет брошен с HTTP-кодом 403.

Нет необходимости изменять код в действиях внутри контроллеров.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector