簡體   English   中英

如何在數據庫級別動態處理Symfony2中的角色|權限:對它們的CRUD操作

[英]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,選民等,但並沒有使我頭腦清醒,但這項研究使我感到非常困惑,因此我需要這里的人提供一些幫助。 然后:

  • 您將如何處理?
  • 在代碼級別有什么例子嗎? (我更喜歡看文字以外的東西來理解整個觀點)
  • ROLES是否與權限相同?

更新:改善問題

我要擁有的是usersroles之間以及groupsroles之間的ManyToMany關系。 我認為,通過SonataUserBundle處理此問題的方法是,在user表中創建列roles ,並為每個用戶分配很多角色,如果我沒記錯的話甚至創建新角色,但是如果我想創建盡可能多的角色呢?而不將它們分配給用戶,以后再向用戶甚至向組添加許多角色?

你會怎么做?

您可以FOSUserBundleFOSUserBundle添加新角色。 您無需首先將其添加到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM