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