使用注释将对 Symfony 3.4 route/method 的访问限制为一个特定角色

Restrict access to Symfony 3.4 route/method to one specific role using annotations

我在 security.yml 中的角色层次结构如下所示:

role_hierarchy:
    ROLE_SUPERVISOR:   ROLE_USER
    ROLE_MANAGER:      ROLE_SUPERVISOR
    ROLE_SUPPORT:      ROLE_MANAGER
    ROLE_ADMIN:        ROLE_SUPPORT

在我的控制器中,我有以下定义:

/**
 * Collect user details.
 *
 * @Route(
 *      "/course/site/new/customerdetails",
 *      name = "course_site_new_customerdetails"
 * )
 * @IsGranted("IS_AUTHENTICATED_FULLY")
 * @param Request $request
 * @return Response
 */
public function customerDetailsAction(Request $request): Response
{
    // prevent a manager from entering
    if ($this->getUser()->hasRole('ROLE_MANAGER')) {
        return $this->redirectToRoute('supervisor_index');
    }

使用注释,有没有办法阻止经理访问此 method/route,但让主管进入?

我知道明显的变化是重新定义层次结构,但是主管是链中的 "below" 经理。

@IsGranted 仅限于安全选民投票选出的角色和特权(角色由特定选民投票选出),因为您的经理角色显然包括主管角色(无论出于何种原因)。 Hierarchies 从角色的角度来看,它本质上是一棵树,用户角色位于根部,并从该树分支出来。您的角色规则基本上应该是:

ROLE_MANAGER: ROLE_USER
ROLE_SUPERVISOR: ROLE_MANAGER

应该读作"every manager is a user","every supervisor is a manager"。有了那个,@IsGranted('ROLE_SUPERVISOR') 应该就足够了。

但是,您可以使用 @Security 语法更明确地要求用户 returns 在 User::getRoles():

上的特定角色
@Security("'ROLE_SUPERVISOR' in user.getRoles()")

(也许 user.roles 就够了……但我不太确定)。

不要忘记使用子句:

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;

另请注意,角色会在注销前缓存。