[英]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.