HTTP認証アダプタに関するZF2のドキュメントZend\Authentication\Adapter\Http
で説明されているように、を介してHTTPベースの認証を実装しようとしています。
ユーザーエージェントが認証されるまですべての着信リクエストをブロックしたいのですが、これをモジュールに実装する方法がわかりません。
コントローラへのアクセスを拒否するようにZend\Mvcアプリケーションを設定するにはどうすればよいですか?
HTTP認証アダプタに関するZF2のドキュメントZend\Authentication\Adapter\Http
で説明されているように、を介して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
backed byを使用しても、同じ結果を得ることができます。Zend\Authentication\Adapter\Http
BjyAuthorize
@ocramiusの答えは受け入れ答えですしかしbasic_password.txt
あなたは2つのファイルを書く方法を説明するのを忘れていますdigest_passwd.txt
基本Http認証に関するZend2公式ドキュメントによると:
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 ResolverforHTTPAdapterを使用することもできます
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によると