Authentication 使用Zend Framework 2通过HTTP身份验证阻止访问

Authentication 使用Zend Framework 2通过HTTP身份验证阻止访问,authentication,zend-framework2,Authentication,Zend Framework2,我正试图通过Zend\authentication\Adapter\HTTP实现基于HTTP的身份验证,如中所述 我想阻止每个传入的请求,直到用户代理通过身份验证,但是我不确定如何在我的模块中实现这一点 我如何设置Zend\Mvc应用程序以拒绝访问我的控制器?您正在寻找的可能是连接到应用程序事件的侦听器 接下来,您必须通过身份验证适配器阻止对任何操作的访问。首先,定义一个负责生产认证适配器的工厂: 名称空间MyApp\ServiceFactory; 使用Zend\ServiceManager\F

我正试图通过
Zend\authentication\Adapter\HTTP
实现基于HTTP的身份验证,如中所述

我想阻止每个传入的请求,直到用户代理通过身份验证,但是我不确定如何在我的模块中实现这一点


我如何设置Zend\Mvc应用程序以拒绝访问我的控制器?

您正在寻找的可能是连接到应用程序事件的侦听器

接下来,您必须通过身份验证适配器阻止对任何操作的访问。首先,定义一个负责生产认证适配器的工厂:

名称空间MyApp\ServiceFactory;
使用Zend\ServiceManager\FactoryInterface;
使用Zend\ServiceManager\ServiceLocator接口;
使用Zend\Authentication\Adapter\Http作为HttpAdapter;
使用Zend\Authentication\Adapter\Http\FileResolver;
类AuthenticationAdapterFactory实现FactoryInterface
{
公共函数createService(serviceLocator接口$serviceLocator)
{
$config=$serviceLocator->get('config');
$authConfig=$config['my_app']['auth_adapter'];
$authAdapter=newhttpadapter($authConfig['config']);
$basicResolver=新文件解析程序();
$digestResolver=新文件解析程序();
$basicResolver->setFile($authConfig['basic_passwd_file']);
$digestsolver->setFile($authConfig['digest\u passwd\u file']);
$adapter->setbasicsolver($basicsolver);
$adapter->setDigestResolver($digestResolver);
返回$adapter;
}
}
这个工厂基本上会给您一个配置好的auth适配器,并抽象出它的实例化逻辑

让我们继续,将侦听器附加到应用程序的
分派
事件,以便我们可以阻止具有无效身份验证头的任何请求:

名称空间MyApp;
使用Zend\ModuleManager\Feature\ConfigProviderInterface;
使用Zend\ModuleManager\Feature\BootstrapListenerInterface;
使用Zend\EventManager\EventInterface;
使用Zend\Mvc\MvcEvent;
使用Zend\Http\Request作为HttpRequest;
使用Zend\Http\Response作为HttpResponse;
类MyModule实现ConfigProviderInterface、BootstrapListenerInterface
{
公共函数getConfig()
{
//出于可读性考虑,所以将其移出,因为配置非常短
返回require uuuu DIR uuuu.'/config/module.config.php';
}
引导上的公共函数(EventInterface$event)
{
/*@var$application\Zend\Mvc\ApplicationInterface*/
$application=$event->getTarget();
$serviceManager=$application->getServiceManager();
//将所有内容的实例化延迟到可能的最新时刻
$application
->getEventManager()
->附加(函数(MvcEvent$事件)使用($serviceManager){
$request=$event->getRequest();
$response=$event->getResponse();
如果((
$request instanceof HttpRequest
&&$response instanceof HttpResponse
)) {
return;//我们不在HTTP上下文-CLI应用程序中?
}
/*@var$authAdapter\Zend\Authentication\Adapter\Http*/
$authAdapter=$serviceManager->get('MyApp\AuthenticationAdapter');
$authAdapter->setRequest($request);
$authAdapter->setResponse($response);
$result=$adapter->authenticate();
如果($result->isValid()){
return;//一切正常
}
$response->setBody('Access denied');
$response->setStatusCode(HttpResponse::STATUS\u CODE\u 401);
$event->setResult($response);//对应用程序端短路
返回false;//停止事件传播
},MvcEvent::事件(U调度);
}
}
然后是模块默认配置,在本例中它被移动到
MyModule/config/module.config.php

返回数组(
“我的应用程序”=>数组(
“验证适配器”=>数组(
'配置'=>数组(
“接受方案”=>“基本摘要”,
“领域”=>“我的应用程序站点”,
'digest_domains'=>'/my_app/my_site',
'nonce_timeout'=>3600,
),
'basic_passwd_file'=>_DIR__.'/dummy/basic.txt',
“digest\u passwd\u file'=>\uuuuu DIR\uuuuu.'/dummy/digest.txt',
),
),
“服务管理器”=>阵列(
“工厂”=>数组(
“MyApp\AuthenticationAdapter”
=>“MyApp\ServiceFactory\AuthenticationAdapterFactory”,
),
),
);
这是你如何完成任务的关键

显然,您需要在
config/autoload/
目录中放置类似于
my_app.auth.local.php的文件,并使用特定于当前环境的设置(请注意,此文件不应提交到SCM):

的答案是accept Answer,但是您忘记了描述如何编写两个文件
basic\u password.txt
digest\u passwd.txt

根据:

  • basic_passwd.txt
    文件包含用户名、域(与配置中的域相同)和普通密码->
    :\n

  • 摘要\u passwd.txt
    文件包含用户名、域(与您的配置中的域相同)和使用MD5哈希的密码哈希->
    ::\n

例如:

如果
basic_passwd.txt
文件:

user:MyApp Site:password\n
user:MyApp Site:5f4dcc3b5aa765d61d8327deb882cf99\n
然后
摘要\u passwd.txt
文件:

user:MyApp Site:password\n
user:MyApp Site:5f4dcc3b5aa765d61d8327deb882cf99\n

或者,您可以将Apache解析器用于HTTP适配器

use Zend\Authentication\Adapter\Http\ApacheResolver;

$path = 'data/htpasswd';

// Inject at instantiation:
$resolver = new ApacheResolver($path);

// Or afterwards:
$resolver = new ApacheResolver();
$resolver->setFile($path);

根据

我在Module.php文件“致命错误:调用未定义的方法Zend\Mvc\Application::attach()”中得到了这个错误。我认为这与$application->attach有关。你知道会出什么问题吗?我的