5

HTTP認証アダプタに関するZF2のドキュメントZend\Authentication\Adapter\Httpで説明されているように、を介してHTTPベースの認証を実装しようとしています。

ユーザーエージェントが認証されるまですべての着信リクエストをブロックしたいのですが、これをモジュールに実装する方法がわかりません。

コントローラへのアクセスを拒否するようにZend\Mvcアプリケーションを設定するにはどうすればよいですか?

4

3 に答える 3

11

探しているのは、おそらく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

許可されていないアクションのリスナーロジックを処理する、と組み合わせて、 ZfcUserbacked byを使用しても、同じ結果を得ることができます。Zend\Authentication\Adapter\HttpBjyAuthorize

于 2013-03-18T01:55:33.387 に答える
1

@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
于 2015-09-02T15:58:29.097 に答える
0

または、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によると

于 2016-08-12T11:05:49.967 に答える