簡體   English   中英

Symfony2,路由和訪問驗證器

[英]Symfony2, routes and access validator

假設我們有用戶和帖子。 帖子鏈接在哪里

localhost/post/{postID}

我如何檢查sf2級安全性是該帖子的用戶所有者(如果不是,請重定向)? 我知道的解決方案不多,但不想使用它(我不想在這里討論原因)。

I.簡單檢查控制器。 這看起來像簡單的檢查(通過服務或實際操作)。

if ($this->isOwner()){
return $this->redirect(...);
}

II。 通過EventListener。 這種情況更好,但不是很好,因為我需要在每個路由上設置特定規則。 而且此偵聽器將每次執行一次,即使它具有檢查器(是否執行檢查),我也不要。

還有其他解決方案嗎?

同樣有趣的是,如何檢查“具有編輯/刪除現有帖子的用戶權限”。

您可以創建一個PostAuthorizer其任務是檢查用戶是否可以在帖子上做某事。 為此,您可以注入AuthenticatedUserProvider ,以便直接在PostAuthorizer獲取經過身份驗證的用戶。

1創建一個AuthenticatedUserProvider (我想您像所有人一樣都在使用FOSUserBundle)。

<?php

namespace Acme\PostBundle\Security;

use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\UserBundle\Model\UserInterface;

/**
 * Provides the authenticated user
 */
class AuthenticatedUserProvider
{
    /**
     * The security context
     *
     * @var SecurityContextInterface
     */
    protected $securityContext;

    public function __construct(SecurityContextInterface $securityContext)
    {
        $this->securityContext = $securityContext;
    }

    /**
     * Gets the current authenticated user
     *
     * @return UserInterface
     */
    public function getAuthenticatedUser()
    {
        $user = $this->securityContext->getToken()->getUser();

        if (!$user instanceof UserInterface) {
            throw new AccessDeniedException('Must be logged in with a UserInterface instance');
        }

        return $user;
    }
}

2並將其聲明為服務:

services:
    #Authenticated User Provider
    acme_post.autenticated_user.provider:
        class: Acme\PostBundle\Security\AuthenticatedUserProvider
        arguments:
            securityContext: "@security.context"

3創建一個PostAuthorizer

<?php

namespace Acme\PostBundle\Security;

use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Acme\PostBundle\Entity\PostInterface;
use Acme\PostBundle\Security\AuthenticatedUserProvider;

/**
 * Manages permissions to manipulate posts
 */
class PostAuthorizer
{
    /**
     * The user provider
     *
     * @var AuthenticatedUserProvider
     */
    protected $authenticatedUserProvider;

    public function __construct(AuthenticatedUserProvider $authenticatedUserProvider)
    {
        $this->authenticatedUserProvider = $authenticatedUserProvider;
    }

    /**
     * Tells if the current user is allowed
     * to see this post
     *
     * @param PostInterface $post
     * @return boolean
     */
    public function canSeePost(PostInterface $post)
    {
        return ($this->getAuthenticatedUser()->getId()  === $post->getOwner()->getId());
    }

    /**
     * Tells if the current participant is allowed
     * to delete this post
     *
     * @param PostInterface $post
     * @return boolean
     */
    public function canDeletePost(PostInterface $post)
    {
        return $this->canSeePost($post);
    }

    /**
     * Tells if the current participant is allowed
     * to edit this post
     *
     * @param PostInterface $post
     * @return boolean
     */
    public function canEditPost(PostInterface $post)
    {
       return $this->canSeePost($post);
    }

    /**
     * Gets the current authenticated user
     *
     * @return FOS\UserBundle\Model\UserInterface
     */

    protected function getAuthenticatedUser()
    {
        return $this->authenticatedUserProvider->getAuthenticatedUser();
    }
}

4並將其聲明為服務

services:
    acme_post.post.authorizer:
        class: Acme\PostBundle\Security\PostAuthorizer
        arguments:
            authenticatedUserProvider: "@acme_post.autenticated_user.provider"

5最后,在您的控制器中(或者如果需要,在帖子提供者中),您只需執行以下操作:

if( !$this->container->get('acme_post.post.authorizer')->canSeePost($post) ) {
    throw new AccessDeniedException('You are not allowed to see this post');
}

// can safely display the post now

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM