認可ミドルウェア

承認はミドルウェアとしてアプリケーションに適用されます。 AuthorizationMiddlewareは、次の役割を処理します:

  • 必要に応じてcancanResultapplyScopeメソッドを追加するデコレーターでリクエストの「アイデンティティ」を装飾します。
  • リクエストで承認がチェック/バイパスされていることを確認します。

ミドルウェアを使用するには、アプリケーションクラスにAuthorizationServiceProviderInterfaceを実装します。次に、アプリインスタンスをミドルウェアに渡し、ミドルウェアをキューに追加します。

基本的な例は次のとおりです:

namespace App;

use Authorization\AuthorizationService;
use Authorization\AuthorizationServiceProviderInterface;
use Authorization\Middleware\AuthorizationMiddleware;
use Authorization\Policy\OrmResolver;
use Cake\Http\BaseApplication;

class Application extends BaseApplication implements AuthorizationServiceProviderInterface
{
    public function getAuthorizationService(ServerRequestInterface $request, ResponseInterface $response)
    {
        $resolver = new OrmResolver();

        return new AuthorizationService($resolver);
    }

    public function middleware($middlewareQueue)
    {
        // other middleware
        $middlewareQueue->add(new AuthorizationMiddleware($this));

        return $middlewareQueue;
    }
}

認可サービスには、ポリシーリゾルバが必要です。利用可能なリゾルバとその使用方法については、ポリシーのドキュメントを参照してください。

アイデンティティデコレータ

デフォルトでは、リクエストのIDAuthorization\IdentityDecoratorで装飾(ラップ)されます。デコレータクラスのプロキシメソッドの呼び出し、装飾されたIDオブジェクトへの配列アクセスとプロパティアクセス。基になるIDに直接アクセスするには、getOriginalData()を使用します:

$originalUser = $user->getOriginalData();

アプリケーションがcakephp/authenticationプラグインを使用している場合、Authorization\Identityクラスが使用されます。このクラスは、Authorization\IdentityInterfaceに加えて、Authentication\IdentityInterfaceを実装します。これにより、認証ライブラリのコンポーネントとヘルパーを使用して、装飾されたIDを取得できます。

ユーザークラスをIDとして使用する

既存のユーザーまたはIDクラスがある場合は、Authorization\IdentityInterfaceを実装し、identityDecoratorミドルウェアオプションを使用して、デコレーターをスキップできます。 まず、ユーザークラスを更新します:

namespace App\Model\Entity;

use Authorization\AuthorizationServiceInterface;
use Authorization\IdentityInterface;
use Authorization\Policy\ResultInterface;
use Cake\ORM\Entity;

class User extends Entity implements IdentityInterface
{
    /**
     * Authorization\IdentityInterface method
     */
    public function can($action, $resource)
    {
        return $this->authorization->can($this, $action, $resource);
    }

    /**
     * Authorization\IdentityInterface method
     */
    public function canResult($action, $resource): ResultInterface
    {
        return $this->authorization->canResult($this, $action, $resource);
    }

    /**
     * Authorization\IdentityInterface method
     */
    public function applyScope($action, $resource)
    {
        return $this->authorization->applyScope($this, $action, $resource);
    }

    /**
     * Authorization\IdentityInterface method
     */
    public function getOriginalData()
    {
        return $this;
    }

    /**
     * Setter to be used by the middleware.
     */
    public function setAuthorization(AuthorizationServiceInterface $service)
    {
        $this->authorization = $service;

        return $this;
    }

    // Other methods
}

ユーザーが必要なインターフェースを実装したので、ミドルウェアのセットアップを更新します:

// In your Application::middleware() method;

// Authorization
$middlewareQueue->add(new AuthorizationMiddleware($this, [
    'identityDecorator' => function ($auth, $user) {
        return $user->setAuthorization($auth);
    }
]));

既存のタイプヒントを変更する必要がなくなり、ユーザーにアクセスできる場所であればどこでも承認ポリシーの使用を開始できます。

承認が確実に適用されるようにする

デフォルトでは、AuthorizationMiddlewareは、IDを含む各リクエストにも承認がチェック/バイパスされていることを確認します。 承認がチェックされていない場合、AuthorizationRequiredExceptionが発生します。 この例外は、他のミドルウェア/コントローラーのアクションが完了したに発生するため、不正アクセスを防止するためにこれに依存することはできませんが、開発/テスト中は役立ちます。 この動作はオプションで無効にできます:

$middlewareQueue->add(new AuthorizationMiddleware($this, [
    'requireAuthorizationCheck' => false
]));

不正なリクエストの処理

デフォルトでは、アプリケーションによってスローされた許可例外は、ミドルウェアによって再スローされます。不正なリクエストのハンドラーを構成し、カスタムアクションを実行できます。
例:ユーザーをログインページにリダイレクトします。

組み込みハンドラは次のとおりです:

  • Exception - このハンドラーは例外を再スローします。これはミドルウェアのデフォルトの動作です。
  • Redirect - このハンドラーは、指定されたURLにリクエストをリダイレクトします。
  • CakeRedirect - CakePHPルーターをサポートするハンドラーをリダイレクトします。

両方のリダイレクトハンドラーは同じ構成オプションを共有します:

  • url - リダイレクト先のURL(CakeRedirectはCakePHPルーター構文をサポートしています)。
  • exceptions - リダイレクトする必要がある例外クラスのリスト。 デフォルトでは、MissingIdentityExceptionのみがリダイレクトされます。
  • queryParam - アクセスされたリクエストURLは、リダイレクトURLクエリパラメータ(デフォルトではredirect)にアタッチされます。
  • statusCode - リダイレクトのHTTPステータスコード。デフォルトは302

例:

$middlewareQueue->add(new AuthorizationMiddleware($this, [
    'unauthorizedHandler' => [
        'className' => 'Authorization.Redirect',
        'url' => '/users/login',
        'queryParam' => 'redirectUrl',
        'exceptions' => [
            MissingIdentityException::class,
            OtherException::class,
        ],
    ],
]));

独自のハンドラーを追加することもできます。ハンドラーはAuthorization\Middleware\UnauthorizedHandler\HandlerInterfaceを実装し、ハンドラーサフィックスが付き、アプリまたはプラグインのMiddleware\UnauthorizedHandler名前空間の下に存在する必要があります。

構成オプションは、最後のパラメーターとしてハンドラーのhandle()メソッドに渡されます。

ハンドラーは、Authorization\Exception\Exceptionクラスを拡張する例外のみをキャッチします。