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

Symfony 4.4中如何在@IsGranted注解中使用OR逻辑

Symfony 4.4 实现权限的 OR 逻辑方案

针对你的需求,由于 Symfony 4.4 不支持 @Security 注解,你可以通过以下几种方式实现两个权限的 OR 逻辑:

方法一:控制器内手动检查权限

直接在控制器方法中注入权限检查器,手动判断两个权限是否满足其一:

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

// 控制器方法
public function yourAction(Module $module, Cm $cm, AuthorizationCheckerInterface $authChecker)
{
    // 检查是否满足任一权限
    $hasModulePermission = $authChecker->isGranted(ModulePermission::MODULE_MODERATOR, $module);
    $hasItemPermission = $authChecker->isGranted(ItemPermission::DELETE_ITEM, $cm);

    if (!$hasModulePermission && !$hasItemPermission) {
        throw new AccessDeniedException('无访问权限');
    }

    // 后续业务逻辑
}

方法二:使用 @IsGranted 的 allow_if 参数

Symfony 4.4 的 @IsGranted 注解支持 allow_if 表达式参数,可以直接在注解中编写 OR 逻辑:

use Symfony\Component\Security\Core\Annotation\IsGranted;

/**
 * @IsGranted(
 *     allow_if="is_granted('" . ModulePermission::MODULE_MODERATOR . "', module) or is_granted('" . ItemPermission::DELETE_ITEM . "', cm)"
 * )
 */
public function yourAction(Module $module, Cm $cm)
{
    // 后续业务逻辑
}

注意:需要用字符串拼接引入常量值,确保表达式使用权限的实际字符串标识;同时方法参数名称($module、$cm)要和表达式中的变量名一致。

方法三:自定义权限投票器(Voter)

如果需要在多个控制器复用该逻辑,可以创建自定义 Voter 封装 OR 判断:

  1. 创建自定义 Voter 类:
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;

class ModuleOrItemVoter extends Voter
{
    public const MODULE_OR_ITEM_ACCESS = 'MODULE_OR_ITEM_ACCESS';

    private $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }

    protected function supports(string $attribute, $subject): bool
    {
        // 只处理自定义权限标识,且subject是包含module和cm的数组
        return $attribute === self::MODULE_OR_ITEM_ACCESS && is_array($subject) && isset($subject['module'], $subject['cm']);
    }

    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
    {
        return $this->security->isGranted(ModulePermission::MODULE_MODERATOR, $subject['module'])
            || $this->security->isGranted(ItemPermission::DELETE_ITEM, $subject['cm']);
    }
}
  1. 在控制器中使用:
/**
 * @IsGranted(
 *     ModuleOrItemVoter::MODULE_OR_ITEM_ACCESS,
 *     subject={"module" = "module", "cm" = "cm"}
 * )
 */
public function yourAction(Module $module, Cm $cm)
{
    // 后续业务逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:32:49