2011-10-13 8 views
6

ユーザーが保護されたURLにアクセスしようとしていて、でない場合、コードを実行する必要があるという状況があります。は認証/承認されています。URL /ルートがプログラムでファイアウォールの背後で保護されているかどうか確認できますか?

デフォルトでは、Symfonyはユーザをログインフォームにリダイレクトまたは転送することによって、認証されていないユーザを処理します。リクエストメソッドがPOSTで、代わりにJSONオブジェクトをエコーし​​た場合、これが起こらないようにしたいと思います。

  • かどうかをチェックするPOSTをリクエストメソッドがある場合

    • チェック:私はこれを処理すると考えることができ

      最良の方法は、kernel.requestイベントをリッスンし、二つのことをチェックするカスタム・リスナーを作成することですユーザーは完全に 認証済み

    POSTリクエストで、ユーザーが完全に認証されていない場合は、JSONオブジェクトをエコーし​​ます。

    しかし、私のリスナーはすべてのリクエストに対して(期待どおり)発砲しています。要求がファイアウォールで保護されているURLのものかどうかをチェックするように制限したいと思います。これを計画的にチェックすることは可能ですか?

    は、私はまた、このについて移動する簡単な方法がありますしつこい疑いを持っていますが、誰もが任意のヒントを持っている場合、私は彼ら:)

    編集を聞いてみたいので、それを把握することはできません
    @@問題 - ファイアウォールされたリクエストのみをチェックする理由は、ファイアウォールされていないリクエストがいくつかあり、コードが実行された場合、リクエストの実際の応答ではなく、前述のJSONオブジェクトを受け取ります。

    私がログインしていない場合、api/get/something(ファイアウォールの後ろにある)にPOSTリクエストを行うと、Symfonyはログインページを記述するHTMLを返します。代わりに、私はちょうど{error: 'User is not authorized'}のような何かをエコーし​​たいです。しかし、私はこれがPOST要求に対してのみ起こるようにしたい。

  • +0

    ファイアウォールで保護されたリクエストをチェックする理由は何ですか? – Problematic

    +0

    @Problematic、私の編集 –

    答えて

    3

    私はこれを間違った方法で行っていたと思います。ファイアウォールの後ろにURLがあるかどうかを知りたかったのですが、現在のユーザーがリクエストに対して許可されているかどうかを調べるべきだったと思います。要するに、ユーザーがURLへのアクセスを拒否されたことを知るということは、URLがファイアウォールの背後になければならないことを意味します。そうでなければ、アクセスは拒否できませんでした。

    これを念頭に置き、私が望む最終結果を得ることができました。あなたは、セキュリティ・メカニズムがどのように機能するかを理解たらそれは

    • Symfony\Component\Security\Http\Firewall

      kernel.requestイベントをリッスン...非常に単純ですファイアウォールは、その後、任意のセキュリティ違反した場合security.yml
    • に登録されているイベントリスナーの数を呼び出す
    • (すなわち、ログインしていないものにアクセスしようとしているユーザ)が検出された場合、AccessDeniedExceptionがスローされ、kernel.exceptionイベントが送出されます。
    • Symfony/Component/Security/Http/Firewall/ExceptionListenerはイベントをリッスンし、次のステップが何であるかを決定するonKernelExceptionメソッドを起動します。認証プロセスを開始すると、私は避けたかったものですので、私の場合には、それが認証プロセス

    を開始すると、私はsymfonyのExceptionListenerを行う前kernel.exceptionを傍受し、私自身のイベントリスナーを書きました。限り、ユーザーが許可されていないよう

    public function handleException(GetResponseForExceptionEvent $event) { 
         $exception = $event->getException(); 
         $request = $event->getRequest(); 
         if ($request->getMethod() == 'POST') { 
          if ($exception instanceof AccessDeniedException) { 
           $response = new Response({err: 'not logged in'}); 
           $event->setResponse($response); 
          } 
         } 
        } 
    

    、とリクエストメソッドがPOSTで、JSONオブジェクトが返されます。私は、これは私が書いた方法であり、1

    の優先順位私のイベントリスナーを与えました(これはまた、イベントの伝播を止める)、ログインページのHTMLではなく。そうでなければ、kernel.exceptionの他のリスナーが反応し、Symfonyはそのビジネスに取り組むことができます。

    したがって、元の質問には未回答のままですが、ユーザーがアクションにアクセスできるかどうかを確認することで達成できると思います。 Symfony\Component\Security\Core\Authorization\AccessDecisionManagerはこれに役立つようです。

    編集
    この方法のみ私はまだそれをテストしていません。ログインしていないユーザーを処理しますが、私は(ログイン)場合、それはまた、発火すると思うなら、私にはわかりませんユーザーは、付与されていない役割を必要とするアクションにアクセスしようとします。これにより問題が発生した場合は、Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverisFullFledged($token)メソッドを使用して、ログインしていないユーザーのみを気にするようにしてください。

    +0

    を参照してください。jsonレスポンスを送信する場合は、$ request-> isXmlHttpRequest()を使用してajaxリクエストかどうかを確認する必要があります。これは、私がデフォルトの認証メソッドをajaxメソッドにするために使用したものです。 – HappyDeveloper

    +0

    @HappyDeveloperのヒントはありがたいですが、まだ定期的なフォームのログインを使用しています。私は、保護されたアクションに対するPOST要求が行われていて、ユーザーがログインしていなかった場合に、別の反応をする必要がありました。 –

    関連する問題