Zend框架2:为两个不同的模块添加不同的身份验证适配器

时间:2015-03-19 14:14:30

标签: events authentication routing zend-framework2 collision

我有两个不同的模块。现在我需要为两个模块添加不同的身份验证机制。

所以我添加了事件代码第一个模块&Modules.php的onBootstrap方法

$listener = $serviceManager->get('First\Service\AuthListener');
$listener->setAdapter($serviceManager->get('First\Service\BasicAuthAdapter'));
$eventManager->attach(MvcEvent::EVENT_ROUTE, $listener, 0);

和第二个模块的Module.php onBootstrap方法

$listener = $serviceManager->get('Second\Service\AuthListener');
$listener->setAdapter($serviceManager->get('Second\Service\AdvAuthAdapter'));
$eventManager->attach(MvcEvent::EVENT_ROUTE, $listener, 0);

现在,如果我禁用其中一个模块,功能正常并请求正确验证。虽然启用两个模块都可以进行某种重叠,所以即使需要的模块也经过了适当的认证,但是其他模块事件代码也被执行了,系统也没有经过验证的错误。

我在想这是因为两个module.php中的事件处理程序代码都是在没有处理请求的模块URL的情况下执行的。

我可以在验证之前验证所请求的路由模式,但这看起来像是一个黑客而不是好的解决方案。

如果存在更好的解决方案来处理此问题?

更新: 我的AuthListener代码:

namespace First\Service;
use Zend\Authentication\Adapter\AdapterInterface;
use Zend\Mvc\MvcEvent;

class AuthListener
{
    protected $adapter;

    public function setAdapter(AdapterInterface $adapter)
    {
        $this->adapter = $adapter;
    }

    public function __invoke(MvcEvent $event)
    {
        $result = $this->adapter->authenticate();

        if (!$result->isValid()) {

            $response = $event->getResponse();

            // Set some response content
            $response->setStatusCode(401);

            $routeMatch = $event->getRouteMatch();
            $routeMatch->setParam('controller', 'First\Controller\Error');
            $routeMatch->setParam('action', 'Auth');
        }
    }
}

1 个答案:

答案 0 :(得分:4)

有一种很好的方法可以使用模块特定的引导程序 - 使用SharedManager

$e->getApplication()->getEventManager()->getSharedManager()
  ->attach(__NAMESPACE__, 'dispatch', function(MvcEvent $e) {

     // This code will be executed for all controllers in current __NAMESPACE__

}, 100);

Here是了解EventManagerSharedEventManager

之间区别的好文章

问题中没有关于听众的其他信息,但我试着猜测:

  • 如果您使用某个callable课程作为听众,那么就可以了,只需用function() { }替换$listener即可。
  • 如果你使用某个类作为监听器,那就实现了 ListenerAggregateInterface,你应该将听众转换为 SharedListenerAggregateInterface并使用方法attachAggregate 而不是attach

我希望它有所帮助!