2016-07-28 31 views
1

我是Symfony的新手。我试图在管理区使用选民。Symfony选民:拒绝访问,用户既不是匿名的,也不记得我

我希望管理员(ROLE_ADMIN)只有在他是superAdmin(ROLE_SUPER_ADMIN)时才能删除(删除)用户。

我的防火墙似乎工作正常,因为我可以登录管理区域,做我想要的东西,直到我不使用选民。这里是我的CURENT用户对象的转储:

User {#300 ▼ 
    -id: 1 
    -password: "$2y$13$e3LL2N/pYGrGn.7EFikqSuAMSkLolcnggtf1HsBgNMzdXnal1AIua" 
    -username: "JustMe" 
    -email: "[email protected]" 
    -isActive: true 
    -roles: array:1 [▼ 
    0 => "ROLE_ADMIN" 
    ] 
} 

,只要我在我的控制器使用denyUnlessGranted()我得到这个异常:

DEBUG - Access denied, the user is neither anonymous, nor remember-me. 
ERROR - Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: "Access Denied." at /Volumes/Work/MAMP htdocs/a-symfony-re/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php line 119 

这是我的安全配置:

role_hierarchy: 
    ROLE_AUTHOR: ROLE_USER 
    ROLE_EDITOR: ROLE_AUTHOR 
    ROLE_ADMIN : [ROLE_USER, ROLE_ALLOWED_TO_SWITCH] 

firewalls: 
    # disables authentication for assets and the profiler, adapt it according to your needs 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 

    main: 
     anonymous: ~ 
     pattern: ^/ 
     provider: app_users_provider 
     form_login: 
      login_path: jst_login 
      check_path: jst_login_check 
     logout: 
      path: jst_logout 
      target:/

access_decision_manager: 
    strategy: unanimous 

这是我的控制器中的一个基本动作,它可以正常工作,直到没有使用选民:

public function deleteUserAction(User $user) 
{ 
    $this->denyAccessUnlessGranted('delete', $user); 
    $currentUser = $this->getUser(); 
    $role = $currentUser->getRoles[0]; 

    return new Response('Delete User AppBundle:AdminController:deleteUser : '.$role); 
} 

这是非常简单的选民:

namespace AppBundle\Security; 

use AppBundle\Entity\User; 
use AppBundle\Entity\Role; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 
use Symfony\Component\Security\Core\Authorization\Voter\Voter; 
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; 

class UserVoter extends Voter 
{ 
    const EDIT = 'edit'; 
    const DELETE = 'delete'; 
    const CREATE = 'create'; 

    private $decisionManager; 

    public function __construct(AccessDecisionManagerInterface, $decisionManager) 
    { 
     $this->decisionManager = $decisionManager; 
    } 

    public function support($attribute, $subject) 
    { 
     if (!in_array($attribute, array(selt::DELETE))) { 
      return false; 
     } 
     if (!$subject instanceOf USER) { 
      return false; 
     } 

     return true; 
    } 

    public function voteOnAttribute($attribute, $subject, TokenInterface $token) 
    { 
     $currentUser = $token->getUser(); 
     $user = $subject; 

     if (!$currentUser instanceOf User) { 
      return false; 
     } 

     switch ($attribute) { 
      case self::DELETE : 
       //return $this->canDelete($token); 
       return $this->canDelete($user, $currentUser); 
       break; 
      default: 
       throw new \LogicException('this code shoudn\'t be executed'); 
     } 
    } 

    private function canDelete($user, $currentUser) 
    { 
     //return $this->decisionManager->decide($token, array('ROLE_ADMIN')); 
     return $currentUser->getRoles()[0] == 'SUPER_ADMIN'; 
    } 
} 

正如你可以看到我已经tryied使用AccessDecisionManagerInterface没有结果..

的Et边heuuu ..任何帮助吗? ;-)

坦克的!

+0

你的'支持'功能中有一个错字:'selt :: DELETE'应该是'self :: DELETE'? – user2203384

+0

你对!但仍然有这个例外.. – jst

回答

0

您的role_hierarchy中的ROLE_SUPER_ADMIN在哪里?

在您的voteOnAttribute函数中试试这个。

case self::DELETE: 
      // if the user is an super admin, allow them to create new posts 
      if ($this->decisionManager->decide($token, array('ROLE_SUPER_ADMIN'))) { 
       return true; 
      } 

当您登录到网站时,您的角色是什么?检查性能分析器

+0

我已经忽略了角色是的,但仍然有这个问题。也试图简单地尝试匹配ROLE_AMDIN,但仍抛出异常。我是在ADMIN_ROLE下登录的 – jst

0

您的安全配置中没有角色ROLE_SUPER_ADMIN。评论后

role_hierarchy: 
    ROLE_AUTHOR: ROLE_USER 
    ROLE_EDITOR: ROLE_AUTHOR 
    ROLE_ADMIN : [ROLE_USER, ROLE_ALLOWED_TO_SWITCH] 
    ROLE_SUPER_ADMIN: ROLE_ADMIN 
... 

更新

//return $this->decisionManager->decide($token, array('ROLE_ADMIN'));的问题是,哪里是你的逻辑定义,如果用户可以删除另一个问题: 在你的角色层次添加呢? DecisionManager不知道您是否未实现该接口并使用该实例。

对于return $currentUser->getRoles()[0] == 'ROLE_ADMIN';好吧,也许由令牌存储返回的用户有几个角色,并且ROLE_ADMIN不是第一个。在这种情况下可以尝试使用:

return in_array("ROLE_SUPER_ADMIN", $tokenInterface->getUser()->getRoles(); 
+0

是的,我忘记了ROLE_SUPER_ADMIN角色un security.yml,但仍然抛出相同的错误。任何方式,我也试图简化VOTER试图匹配ROLE_ADMIN,但仍抛出异常。我已经尝试了2个方法在我的Voter中:return $ this-> decisionManager-> decide($ token,array('ROLE_ADMIN'));并返回$ currentUser-> getRoles()[0] =='ROLE_ADMIN';这两种方法都失败了。 – jst

+0

好吧,我终于在我的代码中发现了一些错误。对于这些建议非常感谢。但似乎有一点值得注意:在Voter自定义类中,我们可以使用AccessDecisionManager,因为它通过检查令牌用户角色来保存逻辑。所以$ this-> decisionManager->决定($ token,array(“ROLE_ADMIN”));效果很好。这里是我的错误和错误:1:昏迷后的构造参数类型,2:不支持的方法“支持”(“支持”是好的),最重要的是,我错过了配置我的服务在app/config/services.yml。 – jst

0

此错误也可以通过symfony的3.0之间的不兼容引起的,并在1.6.0版本中jms/security-extra-bundle

如果您使用jms-security-extra-bundle,请尝试在版本1.6.1或更高版本中使用它!

相关问题