ApiPlatform:子资源路由的安全性

问题描述 投票:0回答:2

我正在将后端从 APIPlateform 2.6 升级到 3.1。 我在配置子资源的安全性时遇到问题,但没有找到任何相关文档。

下面是子资源声明的示例:

#[ApiResource(
    uriTemplate: '/parent-entities/{id}/sub-entities.{_format}',
    operations: [new GetCollection()],
    uriVariables: [
        'id' => new Link(
            fromClass: SubEntityClass::class,
            toClass: ParentEntityClass::class,
            identifiers: ['parentEntity']
        ),
    ],
    security: 'is_granted(\'ROLE_USER\')'
)]

安全当前安全注释工作正常,但我想确保用户可以访问具有 id {id} 的父实体资源。

我已经为 ParentEntity 类指定了一个特定的投票者。

现在,我想添加这样的安全性,但它不起作用:

security: 'is_granted(\'ROLE_USER\')  AND is_granted("VIEW", object.getParentEntity())'

security: 'is_granted(\'ROLE_USER\')  AND is_granted("VIEW", object)'

如果用户无权访问parentEntity资源,我想返回403。

有人有主意吗?

一个解决方案,就是不使用子资源而使用

  1. 在子实体的parentEntity属性上添加API过滤器
    #[ApiFilter(SearchFilter::class, properties: ['parentEntity.id' => 'exact'])]
    private ParentEntity $parentEntity;
  1. 网址是:
    /sub-entities?parent-entity={id}
  2. 添加状态提供者,并以编程方式检查安全性...
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        $parentEntityIds = $context['filters']['parentEntity'] ?? [];
        
        // ...
            if (!$this->authorizationChecker->isGranted('VIEW', $parentEntity)) {
                throw new AccessDeniedException('Access Denied.');
            }
        // ...
    }

我有很多子资源,但不想实现所有这些......

谢谢大家,

马努。

php security api-platform.com symfony6
2个回答
1
投票

据我所知,Api 平台没有提供一种直接的方法来检查基于与标准选民具有多对一关系的父实体的安全性。

不过,可以使用 uriVariable 作为投票者的主题。 像这样定义你的 ApiResource:

#[ApiResource(
    uriTemplate: '/parent_entities/{id}/children.{_format}',
    operations: [new GetCollection()],
    uriVariables: [
        'id' => new Link(
            toProperty: 'parent',
            fromClass: ParentEntity::class, identifiers: ['id']
        )
    ],
    security: 'is_granted("VIEW_BY_ID", id)'
)]

在您的选民中,您可以通过使用“id”主题搜索您的父实体来检查它:

$parent = $this->em->getRepository(Company::class)->findOneBy(['id' => $subject]);
$user = $token->getUser();
return $user !== null && $parent->getOwner()->getId() === $user->getId();

0
投票
#[ApiResource(
    uriTemplate: '/users/{id}/fingers',
    uriVariables: [
        'id' => new Link(
            fromClass: User::class,
            toProperty: 'user', # Refers to App\Entity\Finger::$user
            security: 'is_granted("VOTER_ATTRIBUTE", user)'
        )
    ]
)]
© www.soinside.com 2019 - 2024. All rights reserved.