我試圖通過Zend\Authentication\Adapter\Http
執行基於HTTP的身份驗證,如the ZF2 documentation about the HTTP Authentication Adapter中所述。通過使用Zend Framework進行HTTP身份驗證來阻止訪問
我想阻止每個傳入的請求,直到用戶代理進行身份驗證,但我不確定如何在我的模塊中實現此。
我將如何設置我的Zend \ Mvc應用程序拒絕訪問我的控制器?
我試圖通過Zend\Authentication\Adapter\Http
執行基於HTTP的身份驗證,如the ZF2 documentation about the HTTP Authentication Adapter中所述。通過使用Zend Framework進行HTTP身份驗證來阻止訪問
我想阻止每個傳入的請求,直到用戶代理進行身份驗證,但我不確定如何在我的模塊中實現此。
我將如何設置我的Zend \ Mvc應用程序拒絕訪問我的控制器?
您正在尋找的可能是您的應用程序的Zend\Mvc\MvcEvent::EVENT_DISPATCH
事件附帶的聽衆。
爲了阻止您通過身份驗證適配器訪問任何操作,您需要執行以下操作。首先,定義一個工廠,負責生產的認證適配器:
namespace MyApp\ServiceFactory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Authentication\Adapter\Http as HttpAdapter;
use Zend\Authentication\Adapter\Http\FileResolver;
class AuthenticationAdapterFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('Config');
$authConfig = $config['my_app']['auth_adapter'];
$authAdapter = new HttpAdapter($authConfig['config']);
$basicResolver = new FileResolver();
$digestResolver = new FileResolver();
$basicResolver->setFile($authConfig['basic_passwd_file']);
$digestResolver->setFile($authConfig['digest_passwd_file']);
$adapter->setBasicResolver($basicResolver);
$adapter->setDigestResolver($digestResolver);
return $adapter;
}
}
這家工廠將基本上給你配置的權威性適配器,抽象的實例化邏輯了。
讓我們繼續前進,並附加一個偵聽我們的應用程序的dispatch
事件,使我們可以阻止無效的認證頭的任何請求:
namespace MyApp;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\EventManager\EventInterface;
use Zend\Mvc\MvcEvent;
use Zend\Http\Request as HttpRequest;
use Zend\Http\Response as HttpResponse;
class MyModule implements ConfigProviderInterface, BootstrapListenerInterface
{
public function getConfig()
{
// moved out for readability on SO, since config is pretty short anyway
return require __DIR__ . '/config/module.config.php';
}
public function onBootstrap(EventInterface $event)
{
/* @var $application \Zend\Mvc\ApplicationInterface */
$application = $event->getTarget();
$serviceManager = $application->getServiceManager();
// delaying instantiation of everything to the latest possible moment
$application
->getEventManager()
->attach(function (MvcEvent $event) use ($serviceManager) {
$request = $event->getRequest();
$response = $event->getResponse();
if (! (
$request instanceof HttpRequest
&& $response instanceof HttpResponse
)) {
return; // we're not in HTTP context - CLI application?
}
/* @var $authAdapter \Zend\Authentication\Adapter\Http */
$authAdapter = $serviceManager->get('MyApp\AuthenticationAdapter');
$authAdapter->setRequest($request);
$authAdapter->setResponse($response);
$result = $adapter->authenticate();
if ($result->isValid()) {
return; // everything OK
}
$response->setBody('Access denied');
$response->setStatusCode(HttpResponse::STATUS_CODE_401);
$event->setResult($response); // short-circuit to application end
return false; // stop event propagation
}, MvcEvent::EVENT_DISPATCH);
}
}
,然後模塊默認配置,在這種情況下被轉移到MyModule/config/module.config.php
:
return array(
'my_app' => array(
'auth_adapter' => array(
'config' => array(
'accept_schemes' => 'basic digest',
'realm' => 'MyApp Site',
'digest_domains' => '/my_app /my_site',
'nonce_timeout' => 3600,
),
'basic_passwd_file' => __DIR__ . '/dummy/basic.txt',
'digest_passwd_file' => __DIR__ . '/dummy/digest.txt',
),
),
'service_manager' => array(
'factories' => array(
'MyApp\AuthenticationAdapter'
=> 'MyApp\ServiceFactory\AuthenticationAdapterFactory',
),
),
);
這是你如何完成它的本質。
顯然,你需要放置的東西像一個my_app.auth.local.php
文件在您config/autoload/
目錄,具體到當前環境中的設置(請注意,這個文件不應該被提交到您的SCM):
<?php
return array(
'my_app' => array(
'auth_adapter' => array(
'basic_passwd_file' => __DIR__ . '/real/basic_passwd.txt',
'digest_passwd_file' => __DIR__ . '/real/digest_passwd.txt',
),
),
);
最終,如果您還想要更好的可測試代碼,您可能希望將定義爲閉包的偵聽器移至實現Zend\EventManager\ListenerAggregateInterface
的自己的類。
您可以使用ZfcUser
作爲Zend\Authentication\Adapter\Http
作爲後盾,並結合BjyAuthorize
來實現相同的結果,後者處理未經授權的操作的偵聽器邏輯。
答案@ocramius是接受的答案但你忘了介紹如何編寫兩個文件basic_password.txt
和digest_passwd.txt
根據Zend 2 Official Doc about Basic Http Authentication:
basic_passwd.txt
文件包含用戶名,領域(同一境界進入你的配置)和普通密碼 - ><username>:<realm>:<credentials>\n
digest_passwd.txt
文件包含用戶名,域(同一域到您的配置)和密碼散列使用MD5哈希 - ><username>:<realm>:<credentials hashed>\n
實施例:
如果basic_passwd.txt
文件:
user:MyApp Site:password\n
然後digest_passwd.txt
文件:
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);
根據https://zendframework.github.io/zend-authentication/adapter/http/#resolvers
我得到這個錯誤在Module.php文件「致命錯誤:調用未定義的方法的Zend \的mvc \應用::連接( )」。我認爲這與$ application-> attach有關。你有什麼想法可能是錯的? – 2013-05-31 05:33:17
我的不好 - 應該是'$ application-> getEventManager() - >附加(...)' - 修復 – Ocramius 2013-05-31 08:29:22