2011-11-21 1 views
9

はい、Voter tutorial in cookbookがあります。しかし、私は少し違うものを探しています。私は、ユーザーのIPがデータベースにあるかどうかを確認すること投票者を書いた Symfony2でIPブラックリストを作成するには?

にログインするために特定のIPを拒否

  1. サイト全体にアクセスするために、特定のIPを拒否:私はブラックリストの2つの異なる層が必要です。

    if (VoterInterface::ACCESS_DENIED === $this->voter->vote($token, $this, array())) { 
        throw new AccessDeniedHttpException('Blacklisted, punk!'); 
    } 
    

    最初の問題は、私は本当にそうでない、TokenInterface $tokenを使用するように私を強制され、VoterInterface自体にある:最初のシナリオでは、私はすべての要求を確認し、それが禁止されたユーザに遭遇した場合には403を投げカーネルリスナーを書きましたこの場合の必要性。しかし、それは私が推測するほど重要ではありません。次の事は、実際にAccessDeniedHttpExceptionを使用しなければならないということです。AccessDeniedExceptionは常に私をログインページにリダイレクトしようとし、この場合エンドレスリダイレクトループを引き起こします。それはdev環境で正常に動作しますように私はそれと一緒に暮らすと思いますが、私はprodに切り替えたとき、私はPRODログに次のように503を得続ける:

    [2011-11-21 20:54:04] security.INFO: Populated SecurityContext with an anonymous Token [] []

    [2011-11-21 20:54:04] request.ERROR: Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: Blacklisted, punk! (uncaught exception) at xxx line 28 [] []

    [2011-11-21 20:54:04] request.ERROR: Exception thrown when handling an exception (Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: Blacklisted, punk!) [] []

    私が何を読んでから、それはに問題があるかもしれませんxdebug、しかし私はそれをオフにしても起こります。私もバニラを試しました\Exceptionと同じことをします。なぜそれが起こるのか誰でも知っていますか?そのようなブラックリストのケースのための他の解決策かもしれません。

    また、トークンが割り当てられる前にユーザーを停止する方法がわからないため、2番目のケースを解決する方法はわかりません。現在の解決策はInteractiveLoginEventを扱っており、ユーザーがブラックリストに登録されているかどうかを確認し、ブラックリストに登録されている場合はトークンを削除します。それは安全なものではないようで、私はそれを本当に心地よくはありません。だから、どのようにこの問題を解決するためのアイデアですか?私はちょうどいくつかの明白な "事前ログインイベント"が欠落していると思います。

+0

のために大丈夫です、あなたは括弧の間に例外が処理された例外またはスローされる例外であると思いますか? – greg0ire

+0

私はそれが処理されていると言うでしょうが、何らかのループが起こっていないと思っていました。 –

+0

コードで「処理時に例外がスローされる」を検索すると、2番目のオプションが表示されます。=>ループがあります – greg0ire

答えて

4

ウェブサイト全体へのアクセスを拒否するには、開発環境を保護するために使用されるホワイトリストコードを適合させることができます。 app.phpにこのような何かをスティック:アプリがさえ要求によって打撃を受けるしないよう

if (in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '1.2.3.4',))) { 
    header('HTTP/1.0 403 Forbidden'); 
    exit('You are not allowed to access this site.'); 
} 
+0

これはベストプラクティスではありません。 Insight(Sensioによる分析)は、 "Symfonyイベントシステムをバイパスするので、PHPレスポンス関数(ここではheader()など)を使用することはお勧めできません。代わりにHttpFoundationResponseクラスを使用してください。 "$ _SERVERスーパーグローバルは使用しないでください。"私の応答を参照してください。http://stackoverflow.com/a/34897282/3066708 – johnnyevolunium

+0

@johnnyevoluniumそれは彼らが開発環境のために使用する奇妙なことです。たとえば、CMF配布https://github.com/symfony-cmf/symfony-cmf-standard/blob/master/web/app_dev.php#L16(過去5年間で少し変更されていますが、あなたが言った問題) – MrGlass

+0

Symfony-Cmfはまだ最新ですか?まだSymfony 2.3ですが、Insightはまだありませんでした。 – johnnyevolunium

4

サイト全体のIPの制限については、それは、Apacheのレベルでそれらを処理するのが最善です。あなたがスパム発信者を避けようとしている場合、この方法では時には自動化されたリクエストにリソースを無駄にすることはありません。あなたの場合、.htaccessファイルに拒否ルールを書き込むことが適切です。大規模な設定では、特定のIPをブロックするようにファイアウォールを構成することもできます。そのため、これらの要求はサーバーにまったく衝突しません。

+0

この場合の唯一の問題は、データベースからIPをロードする方法です。それも可能ですか? –

+0

はsymfony2メーリングリストにコメントされています。あなたのアプリにhtaccessファイルに書き込ませてください。私は個人的にはmrglassのソリューションが好きです。 – c33s

4

- そこfilters in EventDispatcherがあるので、あなたは、コントローラの開始処理要求の前にAccessDeniedHttpExceptionを投げることができます。

第2の問題:custom User Providerを使用すると、禁止されたIPアドレスをUserRepositoryで確認できます。

namespace Acme\SecurityBundle\Entity; 
//… some namespaces 
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; 

/** 
* UserRepository 
*/ 
class UserRepository extends … implements … 
{ 

    public function loadUserByUsername($username) 
    { 
     if ($this->isBanned()) { 
      throw new AccessDeniedHttpException("You're banned!"); 
     } 
     //… load user from DB 
    } 

    //… some other methods 

    private function isBanned() 
    { 
     $q = $this->getEntityManager()->createQuery('SELECT b FROM AcmeSecurityBundle:BlackList b WHERE b.ip = :ip') 
      ->setParameter('ip', @$_SERVER['REMOTE_ADDR']) 
      ->setMaxResults(1) 
     ; 
     $blackList = $q->getOneOrNullResult(); 

     //… check if is banned 
    } 

} 
0

を使用してIPおよびIPの範囲をブロックすることができます。 Insight(Sensioによる分析)は、 "Symfonyイベントシステムをバイパスするので、PHPレスポンス関数(ここではheader()など)を使用することはお勧めできません。代わりにHttpFoundationResponseクラスを使用してください。 "$ _SERVERスーパーグローバルは使用しないでください。"

<?php 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 

$loader = require_once __DIR__.'/../app/bootstrap.php.cache'; 

require_once __DIR__.'/../app/AppKernel.php'; 


$request = Request::createFromGlobals(); 

$client_ip = $request->getClientIp(); 
$authorized_hosts = ['127.0.0.1', 'fe80::1', '::1', 'localhost', 'yourIpAddress']; 

// Securisation 
if (!in_array($client_ip, $authorized_hosts)) { 
    $response = new Response(
     "Forbidden", 
     Response::HTTP_FORBIDDEN, 
     array('content-type' => 'text/html') 
    ); 
    $response->send(); 
    exit(); 
} 

$kernel = new AppKernel('prod', false); 
$kernel->loadClassCache(); 
$response = $kernel->handle($request); 
$response->send(); 
$kernel->terminate($request, $response); 

それはエラーメッセージでSensioInsight

関連する問題