2012-03-12 2 views
3

共通のエンティティを共有するが、異なるデータベース設定を使用する複数のsymfony2アプリケーションがあります。これらのデータベースのそれぞれは、テーブルuser,user_roleおよびroleを有する。ここで Symfony2は複数のアプリケーション間でユーザーを共有しています

はキャッチです:私は、そのユーザーが www.myproject.com/app1/loginを訪問し、既存のトークン ONLY同じユーザーが app2のデータベース(同じユーザ名に存在する場合、パスワードを使用する /app2/にURLを変更した後 app1にログインできるようにしたいと思いますと塩)。 現在はrefreshUser()が呼び出されているとき、私は本当に見ることができない

...あなたは、かなり不便同意しなければならない、ある同じユーザ名のみをチェック...: -/

すべてのアプリケーションは、同じ使用しますUserおよびRoleエンティティとUserRepositoryです。

ご協力いただければ幸いです。

UserRepository:

class UserRepository extends EntityRepository implements \Symfony\Component\Security\Core\User\UserProviderInterface{ 
    /** @var User */ 
    private $user; 

    public function loadUserByUsername($username) { 
     /** @var $Q \Doctrine\ORM\Query */ 
     $Q = $this->getEntityManager() 
     ->createQuery('SELECT u FROM CommonsBundle:User u WHERE u.username = :username') 
     ->setParameters(array(
      'username' => $username 
     )); 
     $user = $Q->getOneOrNullResult(); 
     if ($user == null){ 
      throw new UsernameNotFoundException(""); 
     } 
     return $this->user = $user; 
    } 

    public function refreshUser(UserInterface $user) { 
     return $this->loadUserByUsername($user->getUsername()); 
    } 

    public function supportsClass($class) { 
     return $class === 'CommonsBundle\Entity\User'; 
    } 

    public function findById($id){ 
     return $this->getEntityManager() 
      ->createQuery('SELECT u FROM CommonsBundle:User u WHERE u.id = :id') 
      ->setParameters(array(
      'id' => $id 
      )) 
      ->getOneOrNullResult(); 
    } 
} 

ユーザ#1のequals(たUserInterface):

私は、このメソッドを書くためのきれいな方法があると知っているが、私はこの作業を見た後、それを書き換えます:)

public function equals(UserInterface $user) 
{ 
    if (!$user instanceof User) { 
      return false; 
    } 
    if ($this->password !== $user->getPassword()) { 
      return false; 
    } 

    if ($this->getSalt() !== $user->getSalt()) { 
      return false; 
    } 

    if ($this->username !== $user->getUsername()) { 
      return false; 
    } 

    return true; 

}

答えて

5

あなたの質問は私に考えさせました。 symfony2セキュリティを使用する場合、セッションが有効です。すなわち、ユーザーが匿名ユーザーまたは実ユーザーとして認証されているか、セッションが無効です。

これを念頭に置いて、私はあなたのアプローチがあなたのように働いているとは思っていません。なぜなら、user1がログインし、app1を使用しているからです。今すぐ彼はapp2に切り替わり、データベースにはないので、アクセス権を持たないべきです。今何をする?セッションを無効にしますか?これは彼がapp1に再びログインしなければならないことを意味するでしょう。

サブドメインを使用する場合は、セッションをそのサブドメインに割り当てることができますが、これはユーザーがアプリケーションごとに再度ログインする必要があることを意味します。

symfony2がユーザーのIDをセッションに格納するように見えるので、app1データベースにアクセスしなければ、app1データベース内のどのパスワードとユーザーの役割が分からないのか分かりませんそれを確認してください。

symfony2のセキュリティは、単にそのような動作のために作られていないと思います。このセッションでは、アプリケーション全体の中で同じユーザーと関連することが期待されます。

私はsymfony2がここでは大きな問題だとは思わないしかし、PHPでの全体的な処理。のは、私はSymfony2のなしを示唆しているものを一瞬のために考えてみましょう:

ユーザーがログインすると、店舗のユーザーとロールのセッションで特定の配列に、のように:

user.app1 = array('username','password',array('role1','role2')) 

、APP1にそれぞれの要求にuser.app1がセッションにあるかどうかを確認し、そこからロールを読み込みます。もしそうでなければ、私はuser.app2、user.app3などをチェックします。何も見つからない場合は、ログインにリダイレクトしてください。私が見つけたら、私は同じユーザー名を持つユーザーを検索し、他の値を比較するためにデータベースを照会します。一致する場合は、すべてをデータベースに格納します。そうでない場合は、セッションから次のユーザーを確認してください。

私はsymfony security referenceを探して、いくつかの拡張ポイントを得ました。多分そこから作業することができます。 form_loginにはsuccess_handlerがあるので、上記のようにセッションに配列を追加する必要があります。ファイアウォール自体には、request_matcherentry_pointのようなパラメータがあり、上記のようなチェックを追加することができます。すべてがサービスとして定義されているため、エンティティマネージャとセキュリティコンテキストの注入は問題ありません。

個人的には、設計自体は最適ではないと思うかもしれませんし、すべてのアプリケーションと異なるロールに対して1人のユーザーを使用するようにコードをリファクタリングするほうがよいでしょう。(多くのエンティティマネージャを定義し、すべてのデータベースを統合し、すべてを1つのデータベースに格納します.ACLを使用すると、ユーザーは「間違った」コンテンツを表示できなくなります。

+0

ありがとうございました!過去数日間私はこれについていくつかの研究をしてきましたが、あなたの答えを読んだ後、想像したように私が全面的なアイデアをあきらめなければならないことに気がつきました。しかし、ファイアウォールサービスポイントの使用についての考えは、非常に興味深く、検討する価値があります。 symfonyの公式ドキュメントは、別々のアプリケーションを推奨するのではなく、代わりにバンドルした後に、おそらく後でコードリファクタリングを行う必要があります。とにかく、このような詳細な説明と非常に有益な勧告をいただき、ありがとうございます。 :) –

関連する問題