【问题标题】:Zend ACL throwing exception on non-existing resourcesZend ACL 在不存在的资源上抛出异常
【发布时间】:2014-01-04 00:12:17
【问题描述】:

我正在尝试让 Zend ACL 启动并运行,但我似乎遇到了以下问题:

PHP Fatal error:  Uncaught exception 'Zend\Permissions\Acl\Exception\InvalidArgumentException' with message 'Resource 'article-2' not found' in vendor/zendframework/zend-permissions-acl/Zend/Permissions/Acl/Acl.php:292

当资源未添加到资源列表时,我得到 Zend ACL 抛出和异常的印象。举个例子:

$user1 = 'user-1';
$user2 = 'user-2';

$article1 = 'article-1';
$article2 = 'article-2';

$acl = new Acl();

$acl->addRole( new Role('user') );
$acl->addRole( new Role('user-1'), 'user' );
$acl->addRole( new Role('user-2'), 'user' );

$acl->addResource( $article1 );

$acl->allow( $user1, $article1 );

echo $acl->isAllowed( $user1, $article2 ) ? 'allowed' : 'denied';

如您所见,我创建了 3 个角色,一个通用用户角色和两个用户特定角色。然后我创建了两篇文章,并允许用户 1 访问文章 1。但是,如果我现在测试用户 1 是否可以访问文章 2,BOOM,异常!

`isAllowed' 显然应该只返回 false 而不是抛出异常。假设我有 1000 个用户和 1000 篇文章,这意味着除了指定哪些用户可以访问哪些文章之外,我还需要指定每个用户不能访问哪些文章。这显然会导致可笑的长 ACL 和内存消耗,而且最重要的是,文章不是我唯一的资源类型!

除了将isAllowed 包装在try/catch 中(这显然很笨拙)之外,应对这种奇怪行为的最佳方法是什么?

【问题讨论】:

  • 深入研究,我现在似乎明白为什么会发生这种情况。上面的示例是一个硬编码示例,在动态情况下,要测试的资源将始终添加到 ACL 资源列表中。这意味着上面抛出异常的例子是正确的。

标签: zend-framework2 acl


【解决方案1】:

我不确定你的评论是否意味着你已经没事了。 无论如何,在这种情况下,在您检查是否允许某些内容之前,您可以做的只是:

 if(!$acl ->hasResource($resource))
                $acl -> addResource(new \Zend\Permissions\Acl\Resource\GenericResource($resource));

或者甚至花时间扩展默认的ACL类,所以isAllowed方法首先要包含上面的代码。这将是一个简单的Poka-Yoke 实践,并允许您在必须创建资源的地方维护原始模型,同时提高常见或大多数用例的易用性。

【讨论】:

  • 嗨。感谢您的答复。你是对的。我不明白为什么会抛出异常,但后来我明白了为什么这种行为实际上是正确的。 ACL 需要角色和资源。在像我的问题这样的硬编码场景中,它们都应该存在。在动态创建 ACL 的动态场景中,您始终可以使用两者。但是,您的子类解决方案可能会提供一种优雅地处理这种情况的方法,以防万一......
  • 是的,开发起来可能会很棘手,但有可能,所以如果将来您对 ACL 应该如何满足您的业务规则有一个很好的了解,并且您可以弄清楚如何自动化在某些方面,您可以尝试并创建自己的子类。事实上,我有我的自定义 ACL,它允许我直接在路由器配置中创建访问级别等规则,这非常方便)并且它的工作方式非常有魅力。如果你愿意……准备好享受乐趣吧!
猜你喜欢
  • 2017-04-21
  • 2017-06-22
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多