You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony同一控制器多IsGranted注解不生效问题求解

问题原因

你遇到的问题是因为方法上的多个IsGranted注解默认是逻辑与(AND)关系:访问任意一个路由时,所有注解的权限检查都会执行。当访问app_admin_restock_announcement_create路由时,$restockQueue为null,第二个IsGranted(RestockVoter::EDIT_RESTOCK, 'restockQueue')会尝试用null作为校验主体(subject)进行检查。如果你的Voter中EDIT_RESTOCK逻辑要求主体必须是有效的RestockQueue实例,这一步会返回权限失败,最终导致整体校验不通过——哪怕第一个CREATE_RESTOCK的检查返回true。

解决方案:给IsGranted添加路由条件

通过给每个IsGranted注解添加condition参数,让权限检查仅在对应路由下生效,两个路由的权限校验就不会互相干扰:

#[Route('/announcement/create', name: 'app_admin_restock_announcement_create')]
#[IsGranted(RestockVoter::CREATE_RESTOCK, condition: "request.attributes.get('_route') == 'app_admin_restock_announcement_create'")]
#[Route('/announcement/edit/{id}', name: 'app_admin_restock_announcement_edit')]
#[IsGranted(RestockVoter::EDIT_RESTOCK, 'restockQueue', condition: "request.attributes.get('_route') == 'app_admin_restock_announcement_edit'")]
public function detail(
    ?RestockQueue $restockQueue,
    // ... 其他参数
) {
    // ... 控制器逻辑
}

原理说明

  • condition参数使用Symfony表达式语言,通过request.attributes.get('_route')获取当前访问的路由名称,只有路由匹配时,对应的IsGranted检查才会执行。
  • 访问create路由时,仅校验CREATE_RESTOCK权限;访问edit路由时,仅校验EDIT_RESTOCK权限(此时restockQueue已通过参数转换器正确加载)。

这样无需拆分控制器,纯通过注解就能实现分路由的权限控制。

内容的提问来源于stack exchange,提问作者Talha Amir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:33:33