![](/img/trans.png)
[英]How to dynamic handle roles|permissions in Symfony2: restrict functions with dynamic roles
[英]How to dynamic handle roles|permissions in Symfony2 at database level: CRUD operations over them
我在Symfony 2.8項目中工作,對用戶/組/角色有疑問。 有幾個方式來處理用戶和組,例如SonataUser之上SonataAdmin ,最近EasyAdmin但他們都缺少角色|權限管理,這正是我的疑問:什么是處理他們的正確方法? 是的,我知道我需要在security.yml
上編寫它們,但是我不知道是否可以將其存儲在DB(某處)中,然后從那里讀取。 我對此進行了研究,找到了ACL,選民等,但並沒有使我頭腦清醒,但這項研究使我感到非常困惑,因此我需要這里的人提供一些幫助。 然后:
更新:改善問題
我要擁有的是users
和roles
之間以及groups
和roles
之間的ManyToMany
關系。 我認為,通過SonataUserBundle
處理此問題的方法是,在user
表中創建列roles
,並為每個用戶分配很多角色,如果我沒記錯的話甚至創建新角色,但是如果我想創建盡可能多的角色呢?而不將它們分配給用戶,以后再向用戶甚至向組添加許多角色?
你會怎么做?
您可以FOSUserBundle
在FOSUserBundle
添加新角色。 您無需首先將其添加到security.yml
文件中。
為此,您可以執行以下操作:
$user = new User();
$user->addRole('ROLE_NEWUSER'); //Role Name should begin with 'ROLE_'
或在您的控制器中,您可以獲取當前用戶或任何用戶
$this->getUser();
$user->addRole('ROLE_NEWUSER'); //Role Name should begin with 'ROLE_'
這回答了您的第一部分和第二部分。
對於第三部分, 可以將角色用作權限。 以前,我已經實現了一個結構,在該結構中,我根據用戶角色來限制對頁面的訪問,還根據用戶角色來限制可以更改哪些數據。
更新我為此實現了一個事件偵聽器 ,該偵聽器將偵聽所有稱為onKernelRequest
的內核請求。 由於我的角色也存儲在SQL端,所以我在SQL端做了部分訪問管理,但是在Server端也可以做同樣的事情。 我的事件監聽器看起來像這樣:(這是我所擁有的精簡版本)
class TokenListener
{
protected $em;
protected $token_storage;
protected $templating;
protected $router;
protected $resolver;
public function __construct($em,TokenStorageInterface $token_storage, TwigEngine $templating, Router $router, ControllerResolver $resolver)
{
$this->em = $em;
$this->token_storage = $token_storage;
$this->templating = $templating;
$this->router = $router;
$this->resolver = $resolver;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$route = $request->attributes->get('_route');
$routeArr = array('fos_js_routing_js', 'fos_user_security_login', '_wdt'); //These are excluded routes. These are always allowed. Required for login page
if(!is_int(array_search($route, $routeArr)) && false)
{
$userRoles = $this->token_storage->getToken()->getUser()->getRoles();
if(!in_array('ROLE_NEWUSER', $userRoles))
{
$event->setResponse(new RedirectResponse($this->router->generate('user_management_unauthorized_user', array())));
}
}
}
}
我的services.yml看起來像這樣
services:
app.tokens.action_listener:
class: EventListenerBundle\EventListener\TokenListener
arguments:
entityManager: "@doctrine.orm.entity_manager"
token_storage: "@security.token_storage"
templating: "@templating"
router: "@router"
resolver: "@controller_resolver"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
UPDATE要回答問題的更新部分,您可以做的是擁有另一個roles
實體,您可以預先填充所需的角色,然后與原始User
表建立一對多關系。 然后,如果角色實體中已經存在該角色,則可以使用諸如prePersist or preUpdate Doctrine Lifecycle Events
來檢查何時添加新角色。 那應該可以解決您的問題。 所有這些都將涉及一些調整。 沒有直接的方法可以做到這一點。
這取決於您要如何實現。
一種方法:
將UserProviderInterface
實現為loadByUsername
(在此加載角色和權限)到UserInterface
(您的User
)的實現。
然后實現VoterInterface
。 將其注冊為帶有security.voter
標記的服務,並在security.yml中將其指定為提供程序。 覆蓋vote
功能,以評估從TokenInterface
加載的User
的權限(可能還有角色), TokenInterface
是該功能的第一個參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.