我正在尝试对对象的所有者实施访问控制。我正在使用LexikJWTAuthenticationBundle,当我将检查限制为角色时,访问控制有效,但是在检查对象属性时会引发异常。
我正在使用由作曲家在Symfony 4.3项目上安装的API平台。 PHP是7.2.19。
我可以通过检查角色来成功地将请求限制为登录用户,但是添加诸如“ object.owner == user”之类的请求时,它将失败并显示为“ hydra:description”:“无法访问私有属性App \ Entity \ Vehicle :: $ owner”
这是具有相关字段的实体类。
/**
* @ApiResource(
* collectionOperations={"get"={"access_control"="is_granted('ROLE_USER')"}, "post"={"access_control"="is_granted('ROLE_USER')"}},
* itemOperations={"get"={"access_control"="is_granted('ROLE_USER') and object.owner == user"}, "put"={"access_control"="is_granted('ROLE_USER') and previous_object.owner == user"}},
* normalizationContext={"groups"={"vehicle:read"}},
* denormalizationContext={"groups"={"vehicle:write"}}
* )
* @ORM\Entity(repositoryClass="App\Repository\VehicleRepository")
* @ApiFilter(SearchFilter::class, properties={"owner": "exact"})
*/
class Vehicle
{
/**
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="vehicles")
* @ORM\JoinColumn(nullable=false)
* @Groups({"vehicle:read", "vehicle:write"})
*/
private $owner;
public function getOwner(): User
{
return $this->owner;
}
}
这应该只允许拥有者的用户获取或更新车辆,但始终失败,并显示“ hydra:description”:“无法访问私有属性App \ Entity \ Vehicle :: $ owner”。
如果我删除了“ object.owner == user”注释,但保留了对ROLE_USER的检查,则允许该操作。
答案 0 :(得分:1)
有两种方法可以解决此问题:
只需编写object.getOwner()和previous_object.getOwner()即可代替object.owner。因为所有者属性是私有的,所以访问它的唯一方法是像这样访问它:
/**
* @ApiResource(
* collectionOperations={"get"={"access_control"="is_granted('ROLE_USER')"}, "post"={"access_control"="is_granted('ROLE_USER')"}},
* itemOperations={"get"={"access_control"="is_granted('ROLE_USER') and object.getOwner() == user"}, "put"={"access_control"="is_granted('ROLE_USER') and previous_object.getOwner() == user"}},
* normalizationContext={"groups"={"vehicle:read"}},
* denormalizationContext={"groups"={"vehicle:write"}}
* )
* @ORM\Entity(repositoryClass="App\Repository\VehicleRepository")
* @ApiFilter(SearchFilter::class, properties={"owner": "exact"})
*/
class Vehicle
{
/**
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="vehicles")
* @ORM\JoinColumn(nullable=false)
* @Groups({"vehicle:read", "vehicle:write"})
*/
private $owner;
public function getOwner(): User
{
return $this->owner;
}
}