如何在symfony2服务的代码中检查用户角色?我应该只是将用户角色对象发送到服务,还是有解决方案允许我从服务级别进行检查?
答案 0 :(得分:12)
其他答案是您传递容器而不是授权检查程序。虽然它们工作,但它们对容器产生了严格的依赖性,使得将代码迁移到其他项目变得更加困难。相反,您应该只通过授权检查程序。
以下是symfony docs。
中的示例应用程序/配置/ services.yml
services:
newsletter_manager:
class: "AppBundle\Newsletter\NewsletterManager"
arguments: ["@security.authorization_checker"]
的src /的appbundle /新闻/ NewsletterManager.php
namespace AppBundle\Newsletter;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
// ...
class NewsletterManager
{
protected $authorizationChecker;
public function __construct(AuthorizationCheckerInterface $authorizationChecker)
{
$this->authorizationChecker = $authorizationChecker;
}
public function sendNewsletter()
{
if (false === $this->authorizationChecker->isGranted('ROLE_NEWSLETTER_ADMIN')) {
throw new AccessDeniedException();
}
// ...
}
// ...
}
答案 1 :(得分:2)
假设:
您在服务中注入<?php
use Luracast\Restler\Scope;
use Luracast\Restler\Restler;
use Kiosk\Main;
use Kiosk\Drone\Drone;
require_once __DIR__.'/vendor/autoload.php';
$file = __DIR__ . "/config.json";
$main = new Main($file);
$c = $main->c;
Scope::register('Kiosk\\Drone\\Drone', function () use ($c) {
return new DataTable($c->get('config'), $c->get('logger'));
});
$r = new Restler();
$r->addAPIClass('Luracast\\Restler\\Resources');
$r->addAPIClass('Kiosk\\Drone\\Drone','drone');
$r->addAuthenticationClass('Kiosk\\System\\TokenAuth');
$r->handle();
?>
public function __construct(SecurityContext $ securityContext){ $ this-&gt; securityContext = $ securityContext; }
您正在使用FosUserBundle
你应该能够做到:
security.context
答案 2 :(得分:0)
有关详细信息,请参阅here。
我认为如果在User实体中实现isGranted函数会更容易:
Class User implements UserInterface {
...
public function isGranted($role)
{
return in_array($role, $this->getRoles());
}
}
现在,您可以轻松地在应用程序的每个层中检查授予的角色。在PHP中:
$user->isGranted("USER_ADMIN")
或者在Twig:
user.granted("USER_ADMIN")
如果您需要检查当前用户的角色,可以在Twig中执行此操作:
app.user.granted("USER_ADMIN")
注意:变量&#34; app&#34;是全球定义的。
注意2:如果您在应用的安全区域之外使用此代码,则此代码可能会抛出异常,因为app.user将为NULL。
答案 3 :(得分:0)
答案是,为了能够在服务中使用Symfony2类,您需要使用容器提供服务。
服务定义:
services:
/.../:
class: /.../
arguments: ['@service_container']
服务档案:
使用Symfony \ Component \ DependencyInjection \ ContainerInterface作为Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
答案 4 :(得分:0)
在安全问题上要非常小心你正在做的事情。不要做THIS。
这是因为,您需要了解TokenInterface与UserInterface
不同。
TokenInterface是用户身份验证的接口 信息。
您必须使用它 - 如果您当前的服务中没有令牌,请使用SecurityContext
或AccessDecisionManager
。
注意 :在Symfony中&gt; 2.6,已制作了一些improvements,并且已弃用SecurityContext
,并将其拆分为TokenStorage
和AuthorizationChecker
。因此,您可以继续使用AuthorizationChecker
。
看!甚至FOSUserBundle implementation也谈到了它:
/**
* Never use this to check if this user has access to anything!
*
* Use the SecurityContext, or an implementation of AccessDecisionManager
* instead, e.g.
*
* $securityContext->isGranted('ROLE_USER');
*
* @param string $role
* @return Boolean
*/
function hasRole($role);
了解它的工作原理,例如getRoles,Hierarchical roles等内容。
数据库中的ROLES不值得信任 - 如果您从数据库中获取User对象,并使用您的getRoles()
或者更糟糕的是您创建的特殊isGranted($role)
,他们将不会您期望用户拥有的角色。
This应该是你的圣经,现在你可以理解它们之间的区别:
1 $user->getRoles()
array(2) {
[0]=> string(10) "ROLE_ADMIN"
[1]=> string(9) "ROLE_USER"
}
2 $this->token->getRoles()
array(2) {
[0]=> object(Symfony\Component\Security\Core\Role\Role)
(1) { ["role":"Symfony\Component\Security\Core\Role\Role":private]=> string(10) "ROLE_ADMIN" }
[1]=> object(Symfony\Component\Security\Core\Role\Role)
(1) { ["role":"Symfony\Component\Security\Core\Role\Role":private]=> string(22) "ROLE_ALLOWED_TO_SWITCH" }
[2]=> object(Symfony\Component\Security\Core\Role\Role)
(1) { ["role":"Symfony\Component\Security\Core\Role\Role":private]=> string(9) "ROLE_USER" }
}
3 $this->token->getUser->getRoles()
array(2) {
[0]=> string(10) "ROLE_ADMIN"
[1]=> string(22) "ROLE_ALLOWED_TO_SWITCH"
[2]=> string(9) "ROLE_USER"
}
当你有 security.yml
时security:
role_hierarchy:
ROLE_ADMIN: [ROLE_ALLOWED_TO_SWITCH]