Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony 关系中的API平台GraphQL安全性_Symfony_Security_Graphql_Entity Relationship_Api Platform.com - Fatal编程技术网

Symfony 关系中的API平台GraphQL安全性

Symfony 关系中的API平台GraphQL安全性,symfony,security,graphql,entity-relationship,api-platform.com,Symfony,Security,Graphql,Entity Relationship,Api Platform.com,我的问题是在通过GraphQL使用时实体的安全实现,查询是完美的,它们返回必要的数据,但问题发生在生成查询时,并且多对一关系仅限于具有角色“role_ADMIN”,即使用户具有该角色,查询也会返回数据“是否以匿名方式对\u进行身份验证” 如何添加安全层,以便无法获取受保护关系中的数据? 必须在没有任何角色的情况下查看产品查询 补充资料 GraphQL查询用户管理员 query { userAdmin(id: "api/user_admins/1") {

我的问题是在通过GraphQL使用时实体的安全实现,查询是完美的,它们返回必要的数据,但问题发生在生成查询时,并且多对一关系仅限于具有角色“role_ADMIN”,即使用户具有该角色,查询也会返回数据“是否以匿名方式对\u进行身份验证”

如何添加安全层,以便无法获取受保护关系中的数据?

必须在没有任何角色的情况下查看产品查询

补充资料

GraphQL查询用户管理员

query {
    userAdmin(id: "api/user_admins/1") {
        id
        name
    }
}
GraphQL查询用户管理结果确定

{
  "errors": [
    {
      "message": "Sorry, but you don't have access",
      "extensions": {
        "category": "graphql"
      }
  ]
}
GraphQL查询产品

query {
    products {
        edges {
            node {
                name
                price
                user {
                    name
                }
            }
        }
    }
}
GraphQL查询产品结果失败

{
  "data": {
    "products": {
      "edges": [
        {
          "node": {
            "name": "GERLACH-HAAG",
            "price": "175",
            "user": {
              "name": "Sidney Deane" /** this information should not be seen **/
            }
          }
        }
      ]
    }
  }
}
实体产品配置

<?php

/**
 * @ApiResource(
 *     graphql={
 *          "item_query",
 *          "collection_query",
 *          "delete"={ "security" = "is_granted('ROLE_ADMIN')" },
 *          "create"={ "security" = "is_granted('ROLE_ADMIN')" },
 *          "update"={ "security" = "is_granted('ROLE_ADMIN')" }
 *     }
 * )
 * @ORM\Table(name="TBL_PRODUCTS")
 * @ORM\Entity(repositoryClass=ProductRepository::class)
 * @ORM\HasLifecycleCallbacks()
 */
class Product
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="bigint", name="ID")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=180, name="NAME")
     */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\UserAdmin")
     * @ORM\JoinColumn(name="USER", referencedColumnName="ID")
     */
    private $user;
<?php

/**
 * @ApiResource(
 *     graphql={
 *          "item_query"={ "security" = "is_granted('ROLE_ADMIN')" },
 *          "collection_query"={ "security" = "is_granted('ROLE_ADMIN')" },
 *          "delete"={ "security" = "is_granted('ROLE_ADMIN')" },
 *          "create"={ "security" = "is_granted('ROLE_ADMIN')" },
 *          "update"={ "security" = "is_granted('ROLE_ADMIN')" }
 *     }
 * )
 * @ORM\Table(name="TBL_USERS_ADMIN")
 * @ORM\Entity(repositoryClass=UserAdminRepository::class)
 * @ORM\HasLifecycleCallbacks()
 */
class UserAdmin implements UserInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="bigint", name="ID")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=180, name="USERNAME")
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=180, name="PASSWORD")
     */
    private $password;

    /**
     * @ORM\Column(type="string", length=180, name="NAME")
     */
    private $name;

尝试在实体上使用排除策略。您将需要使用JMS序列化程序捆绑包

例如:

use JMS\Serializer\Annotation as Serializer;

/**
 * @ORM\Table(name="TBL_PRODUCTS")
 * @ORM\Entity(repositoryClass=ProductRepository::class)
 * @ORM\HasLifecycleCallbacks()
 * @Serializer\ExclusionPolicy("all")
 */

class Product
{
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\UserAdmin")
     * @ORM\JoinColumn(name="USER", referencedColumnName="ID")
     * @Serializer\Groups({"ROLE_ADMIN"}) // only users with ROLE_ADMIN will see this
     * @Serializer\Expose()
     */
    private $user;
    
    /**
     * ...
     * @Serializer\Groups({"ROLE_SUPER_ADMIN"}) // only users with ROLE_SUPER_ADMIN will see this
     * @Serializer\Expose()
     */
    private $superSecretData;

    ...
}
这将仅在用户具有“管理员”角色时公开
$user
属性。 在公开数据的控制器/服务中,应将用户角色添加到序列化上下文:

use JMS\Serializer\SerializerInterface;

...


        $entities = $repository->findAll();

        $responseData = $this->serializer->serialize(
            $entities,
            'json',
            SerializationContext::create()
                ->setGroups(['ROLE_USER']) // Add all roles you want
        );

        $response = new Response(
            $responseData,
            Response::HTTP_OK
        );

        $response->headers->set('Content-Type', 'application/json');

        return $response;

通过这种方式,您应该能够根据用户的角色排除或公开某些属性。

安全属性允许定义执行给定查询所需的角色或权限。但是,它不定义用户可以通过此查询访问的可用关系。为此,您可以使用

基本上,使用特定的序列化组标记需要在响应中返回特殊角色的属性,例如
@Groups(“admin”)
,然后创建动态序列化上下文生成器以添加特殊组(如果连接的用户具有此特殊角色):

<?php

namespace App\Serializer;

use ApiPlatform\Core\GraphQl\Serializer\SerializerContextBuilderInterface;
use App\Entity\Book;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

final class BookContextBuilder implements SerializerContextBuilderInterface
{
    private $decorated;
    private $authorizationChecker;

    public function __construct(SerializerContextBuilderInterface $decorated, AuthorizationCheckerInterface $authorizationChecker)
    {
        $this->decorated = $decorated;
        $this->authorizationChecker = $authorizationChecker;
    }

    public function create(?string $resourceClass, string $operationName, array $resolverContext, bool $normalization): array
    {
        $context = $this->decorated->create($resourceClass, $operationName, $resolverContext, $normalization);
        $resourceClass = $context['resource_class'] ?? null;

        if ($resourceClass === Book::class && isset($context['groups']) && $this->authorizationChecker->isGranted('ROLE_ADMIN') && false === $normalization) {
            $context['groups'][] = 'admin';
        }

        return $context;
    }
}