【问题标题】:zend-authentication - setting identity to custom object with rbac roles loadedzend-authentication - 将身份设置为加载了 rbac 角色的自定义对象
【发布时间】:2018-05-17 14:10:33
【问题描述】:

在 ZF2 项目中,我使用 AuthenticationService 来验证用户登录凭据。这工作正常,除了它只在会话中存储一个包含用户名的字符串。

我希望后续调用 AuthenticationService::getIdentity 以返回自定义 Identity 对象,该对象填充了用户数据库 ID、角色和权限(从 RBAC 服务填充),以便session 更有用一点。

我能够创建此对象,但不确定将其保留在会话中的最佳方式;理想情况下,我想用 Zend_Auth 键覆盖该条目,但这似乎不起作用。

到目前为止我的代码:

<?php
namespace Authentication\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Authentication\AuthenticationService;
use Authentication\Form\Login\LoginForm;
use Zend\Form\Form;
use Authentication\Model\Identity\AuthenticatedIdentity;

class AuthenticationController extends AbstractActionController
{
    /**
    *
    * @var AuthenticationService
    */
    protected $authenticationService;

    /**
    *
    * @var LoginForm
    */
    protected $loginForm;

    /**
    *
    * @param AuthenticationService $authenticationService
    * @param LoginForm $loginForm
    */
    public function __construct(AuthenticationService $authenticationService, LoginForm $loginForm){
        $this->authenticationService = $authenticationService;
        $this->loginForm = $loginForm;
    }

    public function indexAction(){
        $form = $this->loginForm;
        $viewModel = new ViewModel();

        $viewModel->setVariables([
            'loginForm' => $form
        ]);

        if($this->getRequest()->isPost() === false){
            return $viewModel;
        }

        $form->setData($this->getRequest()->getPost());

        if($form->isValid() === false){
            return $viewModel;
        }

        $data = $form->getData();

        $authenticationAdapter = $this->authenticationService->getAdapter();
        $authenticationAdapter->setIdentity($data['credentials']['username'])
            ->setCredential($data['credentials']['password']);
        $authenticationResult = $this->authenticationService->authenticate($authenticationAdapter);

        if($authenticationResult->isValid() === false){
            $viewModel->setVariable('validCredentials', false);
            return $viewModel;
        }

        /**
         * Create a user model and save it to the session.
         */
         $authenticationResultRow = $authenticationAdapter->getResultRowObject(null, ['password']);

        $permissions = $this->rbacService->getPermissionsForUser($authenticationResultRow->user_id);
        $roles = $this->rbacService->getRolesForUser($authenticationResultRow->user_id);

        $identity = new AuthenticatedIdentity(
            $authenticationResult->getIdentity(),
            'admin',
            $permissions,
            $roles
        );
        $identity->setUserId($authenticationResultRow->user_id);

        //how to store this Identity object in session so AuthenticationService will return it?

        return $this->redirect()->toRoute('dashboard');
    }
}

【问题讨论】:

    标签: zend-framework2 zend-auth


    【解决方案1】:

    查看https://github.com/zendframework/zend-authentication/blob/master/src/AuthenticationService.php#L75https://github.com/zendframework/zend-authentication/blob/master/src/Storage/StorageInterface.php

    您可以像这样将AuthenticatedIdentity 对象直接写入存储:

    $this->authenticationService->getStorage()->write($identity);
    

    但是,我建议不要这样做,因为:

    1. 如果用户的权限/角色在会话期间发生更改,他/她将不得不退出并重新登录才能看到任何对用户不太友好的更改。
    2. 您的 AuthenticatedIdentity 对象及其包含的所有对象都需要可序列化,这可能会导致维护问题。

    我会(并且确实)在需要时从数据库或某种形式的缓存中获取用户对象和/或角色,但不会将其存储在会话中。

    【讨论】:

    • 太完美了,谢谢。在此应用程序中,用户角色不会在会话中更改,如果进行了此类更改,则在会话实例中重置身份将是微不足道的。由于 Identity 对象(取自 ZF2 文档的想法)只是一个简单的容器/值对象,因此可序列化不是问题。感谢您的回答!
    猜你喜欢
    • 2021-07-24
    • 2015-05-11
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多