ZF2 - BjyAuthorize - 如何从数据库获取规则和防护

2024-01-20

我使用 BjyAuthorize 和 Zend Framework2 来实现授权,并且能够成功集成数据库中的角色。现在我想从数据库表中获取我的规则和守卫。我怎样才能做到这一点?


这里最简单的方法和“技巧”实际上是:

  1. 将您的规则和防护设置为与示例配置中所示相同的数组格式。因此,从数据库读取记录后,无论原始数据库数据是什么格式,都应对其进行处理以匹配与配置中相同的保护格式。 (我的回答详细介绍了如何使用 Doctrine ORM 做到这一点,但也应该让您了解其他数据库引擎。只需用您最喜欢的数据库引擎替换“数据库读取”操作即可)

  2. 将已经采用 BjyAuthorize 期望的正确格式的规则(因为您这样做了)注入到BjyAuthorize\Guard\Controller, 从内部YOUR_MODULE_NAME\Factory\DoctrineControllerGuardAdapterFactory,您将编写。 Bjy 的控制器将把这些规则视为来自配置*,并且不会怀疑有任何差异。

  3. 退一步享受吧!

这是您需要在自己的模块中编写的构造:

namespace YOUR_MODULE_NAME\Factory;

/**
 * See "How and where exactly to register the factory" in ZF2 config
 * below in my answer.
 */
class [Custom]ControllerGuardAdapterFactory 
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        /**
         * Retrieve your rules from favorive DB engine (or anything)
         *
         * (You may use $serviceLocator to get config for you DB engine)
         * (You may use $serviceLocator to get your DB engine)
         * (You may use $serviceLocator to get ORM Entity for your DB engine)
         * (Or you may hack your DB connection and retrieval in some other way)
         *
         * Hell, you may read them from a text file using PHP's file() method
         * and not use $serviceLocator at all
         *
         * You may hardcode the rules yourself right here for all that matters
         */            
        $rules = ... //array(...);


        /** 
         * Inject them into Bjy's Controller
         *
         * Rules must be in the same format as in Bjy config, or it will puke.
         * See how ['guards'][\BjyAuthorize\Guard\Controller::class] is constructed 
         * in Bjy configuration for an example
         */             
        return new \BjyAuthorize\Guard\Controller($rules, $serviceLocator); 
    }
}

现在观察并观察这可以变得多么令人头脑麻木的复杂! (仿照Bjy自己的机制)

这主要是 ZF2、OO 和 Bjy“配置地狱”,伙计们,除此之外没有什么特别的。欢迎来到 ZF2 和 Bjy 以及 ORM 配置地狱。不客气。

详细解答——如何实施​​?

写一个adapter工厂,从数据库读取规则,然后将它们注入到BjyAuthorize 的 Controller Guard https://github.com/bjyoungblood/BjyAuthorize/blob/1.4.0/src/BjyAuthorize/Guard/Controller.php。效果与读取规则的效果相同['guards'][\BjyAuthorize\Guard\Controller::class]

What?

The way BjyAuthorize 的 Controller Guard https://github.com/bjyoungblood/BjyAuthorize/blob/1.4.0/src/BjyAuthorize/Guard/Controller.php有效的方法是它采用某种格式的规则(为['guards']['BjyAuthorize\Guard\Controller']),然后它使用规则来填充 ACL。它还根据规则为您计算资源并将其加载到 ACL 中。如果没有,您将必须编写自己的资源提供程序来执行此操作。

所以任务就变成了:

  • 从数据库加载规则并将规则转换为 BjyAuthorize 期望的格式。这可以在您自己的规则提供程序中完成,很像这个 https://github.com/bjyoungblood/BjyAuthorize/blob/1.4.0/src/BjyAuthorize/Provider/Role/ObjectRepositoryProvider.php.
  • 您可以使用工厂从 module.config.php 文件加载特定的数据库和存储类配置数组。我把我的放在下面['guards']['YOUR_MODULE_NAME_controller_guard_adapter'].
'guards' => array(
        'YOUR_MODULE_NAME_controller_guard_adapter' => array(
            'object_manager' => 'doctrine.entity_manager.orm_default',
            'rule_entity_class' => 'YOUR_MODULE_NAME\Entity\ObjectRepositoryProvider'
        )
)
  • (续)我将其置于保护之下,而不是rule_providers,因为我们在这里处理的不是纯粹的规则提供者。它是一个防护提供程序,或者“从 ObjectRepositoryProvider 中获取规则并将其注入控制器防护的适配器”。这个工厂应该看起来像这样 https://github.com/bjyoungblood/BjyAuthorize/blob/1.4.0/src/BjyAuthorize/Service/ObjectRepositoryRoleProviderFactory.php,只不过您将加载规则,而不是角色。然后,您将把规则注入到控制器中,如下一步所示。
  • 将规则注入到控制器中,就像这里所做的一样 https://github.com/bjyoungblood/BjyAuthorize/blob/1.4.0/src/BjyAuthorize/Service/ControllerGuardServiceFactory.php#L31

示例实施细节(来自评论中的问答)

更多关于“将规则注入控制器”的最后一点。基本上有两个步骤:1)确保您已经(或将)以某种方式生成规则(这是困难的一步)。 2)将这些规则注入控制器(这是更简单的步骤)。实际的注入是这样完成的

$rules = __MAGIC__;  //get rules out of somewhere, somehow.
return new Controller($rules, $serviceLocator); //$rules injection point

请参阅下面的代码块以了解我自己的实现,其中块中的最后一行是我在上面给出的行。

namespace YOUR_MODULE_NAME\Factory;

use BjyAuthorize\Exception\InvalidArgumentException;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use YOUR_MODULE_NAME\Provider\Rule\DoctrineRuleProvider;    //this one's your own
use BjyAuthorize\Guard\Controller;

class DoctrineControllerGuardAdapterFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        //just setting up our config, move along move along...
        $config = $serviceLocator->get('Config');
        $config = $config['bjyauthorize'];

        //making sure we have proper entries in our config... 
        //move along "nothing to see" here....
        if (! isset($config['guards']['YOUR_MODULE_NAME_controller_guard_adapter'])) {
            throw new InvalidArgumentException(
                'Config for "YOUR_MODULE_NAME_controller_guard_adapter" not set'
            );
        }

        //yep all is well we load our own module config here
        $providerConfig = $config['guards']['YOUR_MODULE_NAME_controller_guard_adapter'];

        //more specific checks on config
        if (! isset($providerConfig['rule_entity_class'])) {
            throw new InvalidArgumentException('rule_entity_class not set in the YOUR_MODULE_NAME guards config.');
        }

        if (! isset($providerConfig['object_manager'])) {
            throw new InvalidArgumentException('object_manager not set in the YOUR_MODULE_NAME guards config.');
        }

        /* @var $objectManager \Doctrine\Common\Persistence\ObjectManager */
        $objectManager = $serviceLocator->get($providerConfig['object_manager']);

        //orp -- object repository provider
        //here we get our class that preps the object repository for us
        $orp=new DoctrineRuleProvider($objectManager->getRepository($providerConfig['rule_entity_class']));

        //here we pull the rules out of that object we've created above
        //rules are in the same format BjyAuthorize expects
        $rules=$orp->getRules();

        //here pass our rules to BjyAuthorize's own Guard Controller.  
        //It will not know the difference if we got the rules from Config or from Doctrine or elsewhere,  
        //as long as $rules are in the form it expects.
        return new Controller($rules, $serviceLocator); 
    }
}

教义规则提供者

namespace YOUR_MODULE_NAME\Provider\Rule;

use Doctrine\Common\Persistence\ObjectRepository;
use BjyAuthorize\Provider\Rule\ProviderInterface;

/**
 * Guard provider based on a {@see \Doctrine\Common\Persistence\ObjectRepository}
 */
class DoctrineRuleProvider implements ProviderInterface
{
    /**
     * @var \Doctrine\Common\Persistence\ObjectRepository
     */
    protected $objectRepository;

    /**
     * @param \Doctrine\Common\Persistence\ObjectRepository $objectRepository            
     */
    public function __construct(ObjectRepository $objectRepository)
    {
        $this->objectRepository = $objectRepository;
    }

    /**
     * Here we read rules from DB and put them into an a form that BjyAuthorize's Controller.php understands
     */
    public function getRules()
    {
        //read from object store a set of (role, controller, action) 
        $result = $this->objectRepository->findAll();

        //transform to object BjyAuthorize will understand
        $rules = array();
        foreach ($result as $key => $rule)
        {
            $role=$rule->getRole();
            $controller=$rule->getController();
            $action=$rule->getAction();            

            if ($action==='all')    //action is ommitted
            {
                $rules[$controller]['roles'][] = $role;
                $rules[$controller]['controller'] = array($controller);
            }
            else
            {
                $rules[$controller.':'.$action]['roles'][]=$role;
                $rules[$controller.':'.$action]['controller']=array($controller);
                $rules[$controller.':'.$action]['action']=array($action);
            }                       
        }    

        return array_values($rules);
    }
}

问:工厂具体如何以及在哪里注册DoctrineControllerGuardAdapterFactory

答:试试这个路径:module\YOUR_MODULE_NAME\config\module.config.php并有

'service_manager' => array(
    'factories' => array(
        'YOUR_MODULE_NAME_controller_guard_adapter' => \YOUR_MODULE_NAME\Factory\DoctrineControllerGuardAdapterFactory::class
    )
)
  • Note: YOUR_MODULE_NAME。左边的东西=>标志是“关键”,可以是任何你想要的东西。 Bjy 中的约定是它与实际的类名和路径相似。还有右边的东西=>是您想要使用此键调用的类的实际完全限定命名空间。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ZF2 - BjyAuthorize - 如何从数据库获取规则和防护 的相关文章

随机推荐

  • cmake 上的相对路径/如果之后更改路径,则会出现错误

    我有一个带有自己项目的 VS 12 解决方案 该解决方案依赖于一些依赖项 使用 cmake 生成的项目文件 我使用 cmake 生成了这些 VS12 项目 并将这些项目添加到我的解决方案中 使用相对路径 然后我必须调整这些项目的输出目录 在
  • CentOS 上 PHP 7 的 Memcache 扩展安装失败

    我正在尝试将相当大的 PHP 5 3 代码库升级到 PHP 7 它托管在 CentOS 6 5 上 因此我想将其保留在该操作系统上 我目前正在一个原始 Vagrant 机器上进行此操作 我已成功安装 PHP 7 以及除 Memcache 之
  • 使用 Angular-map 包将 Bingmap 集成到 Angular 6 中

    我正在尝试使用 angular map npm 包在 Angular 6 中实现 bingmap 因为我有refer https www npmjs com package angular maps also referred https
  • 对数字音频进行下采样并应用低通滤波器

    我从 CD 中获得了 44Khz 音频流 表示为 16 位 PCM 样本数组 我想将其削减至 11KHz 流 我怎么做 从多年前我上工程课时起 我就知道流将无法再准确地描述超过 5500Hz 的任何内容 因此我想我也想删除高于此的所有内容
  • Twitter Bootstrap 2:导航栏子菜单链接不起作用

    更新到 Twitter Bootstrap 2 0 非常棒 后 导航链接inside子菜单不起作用 jQuery 版本为 1 7 1 下拉菜单实际上有效 并且标记是正确的 根据文档 div class navbar navbar fixed
  • 如何在VS2010 RDLC报表中添加组页脚

    如何将 组页脚 摘要行添加到我在 VS2010 RLDC 中创建的组中 设计器的底部有行组和列组 单击行组旁边的箭头 然后单击 添加总计 这会添加页脚行 但请注意 如果您在最外面的组上执行此操作 它会添加一个 报告页脚 显示所有组的总计 而
  • 如何使用 scipy.optimize.minimize 进行最大似然回归

    我如何使用最大似然回归scipy optimize minimize 我特别想使用minimize在这里运行 因为我有一个复杂的模型 需要添加一些约束 我目前正在尝试使用以下内容的简单示例 from scipy optimize impor
  • 如果没有 verifyProof、sessionInfo、临时证明或注册 ID,则无法创建 PhoneAuthCredential

    我正在尝试firebase电话验证 在我的电话号码上收到代码后 代码跳转到verifysignincode 方法 创建失败phoneAuthCredentials 程序捕获的异常是 无法创建PhoneAuthCredential没有任何一个
  • 在 Symfony 2 中验证没有形式的实体

    我正在为 Symfony 2 创建一个 REST API 控制器 我开始使用 SensioGeneratorBundle 创建 CRUD 并修改该控制器以充当 REST 控制器 但是 我没有表格 所以我正在考虑删除这部分 如何在没有表单的情
  • 我可以在打字稿中检查联合类型的类型吗?

    有没有一种方法可以针对语言中内置的联合类型对对象进行类似 instanceof 的查询 我有一个带有联合类型的类型别名 如下所示 type MyType Foo Bar Thing Each of Foo Bar and Thing继承自B
  • desiredAccuracy 和 distanceFilter 之间的区别

    很抱歉在这里成为菜鸟 我无法清楚地区分 CLLocationManager 属性距离过滤器 and 期望准确度 如果我希望我的应用程序为即使很小的距离 例如 100 200 米 提供不同的坐标 我应该为这些属性设置什么值 帮助将不胜感激 根
  • Homebrew 说 Xcode 已经过时了

    我正在尝试使用 Homebrew 执行软件包的安装 但是当我尝试运行安装时出现以下错误 错误 您的 Xcode 7 3 1 已过时 请更新到 Xcode 8 0 或删除它 Xcode 可以从 App Store 更新 我想在这台机器上保留
  • 更改 UISearchBar 放大图标颜色和位置

    我有一个 UISearchBar 我想更改初始放大图标 出现在 UISearchBar 中间的图标 的位置以及颜色或图标 到目前为止 我更改了色调和图标图像 但是 只有当我在模拟器上测试应用程序时才会显示新图标 但在实际设备 均运行 iOS
  • 具有索引签名的 keyof 类型运算符

    我正在阅读打字稿docs https www typescriptlang org docs handbook 2 keyof types html the keyof type operator并通过这段代码摘录得出 type Mapis
  • 如何使用通过 NPM 安装的 font Awesome 5

    我没有找到任何下一步该做什么的文档 我通过以下方式将 font awesome 安装到了我的项目中npm npm install save fortawesome fontawesome free webfonts 但现在怎么办 谁能指出我
  • SQL-92 (Filemaker):如何更新序列号列表?

    在其中一个 SortID 发生更改 例如从 444 更改为 444 1 之后 我需要使用 SQL 92 重新分配所有 SortID 从 1 开始 直到 Beleg 表的记录子集的 MAX SortID 我尝试了多种方法 例如 SET a 0
  • 如何让 ECS 任务承担另一个 AWS 账户的角色?

    我有一个审计容器 可以针对各种 AWS API 运行扫描 我希望所有这些都在产品帐户中作为 ECS 任务运行 但扫描其他帐户中的资源 是否可以将另一个帐户的角色设置为任务角色 我尝试过设置taskRoleArn在我的任务定义中从另一个帐户添
  • 如何在Python中创建命名空间包?

    我有一个具有以下结构的 Python 3 项目 project root init py sub init py actualcode py 我想使用 命名空间包 以便我的库与单独项目中的其他相关库共享公共命名空间 导入语句应该如下所示 f
  • 如何使用 OCMock 测试是否在完成处理程序块内调用对象的方法?

    我有一个方法 implementation SomeClass void thisMethod ObjectA objA APIClient connectToAPIWithCompletionHandler id result if re
  • ZF2 - BjyAuthorize - 如何从数据库获取规则和防护

    我使用 BjyAuthorize 和 Zend Framework2 来实现授权 并且能够成功集成数据库中的角色 现在我想从数据库表中获取我的规则和守卫 我怎样才能做到这一点 这里最简单的方法和 技巧 实际上是 将您的规则和防护设置为与示例