Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Session Symfony2跨多个应用程序共享用户_Session_Symfony_Acl - Fatal编程技术网

Session Symfony2跨多个应用程序共享用户

Session Symfony2跨多个应用程序共享用户,session,symfony,acl,Session,Symfony,Acl,我有多个symfony2应用程序,它们共享公共实体,但使用不同的数据库设置。每个数据库都有表user、user\u role和role 这里有一个陷阱:我希望该用户能够通过访问www.myproject.com/app1/login登录app1,并且在将URL更改为/app2/后,仅在app2的数据库中存在相同的用户(相同的用户名、密码和salt)的情况下使用现有令牌。目前,它只检查相同的用户名,这是,你必须同意,相当不方便 我真的看不出何时调用了refreshUser():-/ 所有应用程序都

我有多个symfony2应用程序,它们共享公共实体,但使用不同的数据库设置。每个数据库都有表
user
user\u role
role

这里有一个陷阱:我希望该用户能够通过访问
www.myproject.com/app1/login
登录
app1
,并且在将URL更改为
/app2/
后,仅在
app2
的数据库中存在相同的用户(相同的用户名、密码和salt)的情况下使用现有令牌。目前,它只检查相同的用户名,这是,你必须同意,相当不方便

我真的看不出何时调用了
refreshUser()
:-/

所有应用程序都使用相同的
用户
角色
实体和
用户存储库

任何帮助都将不胜感激

用户存储库:

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();
    }
}
用户等于(用户界面):

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();
    }
}
我知道有一种更漂亮的方法来编写这个方法,但我会在看到这个工作之后重写它:)


}

您的问题让我思考。使用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,你得到了一些扩展点,也许你可以从那里开始工作。
form\u login
获得了一个
success\u处理程序
,因此应该按照上面的建议将数组添加到会话中。防火墙本身有一些参数,如
request\u matcher
entry\u point
,可用于添加额外的检查,如我上面提到的检查。所有这些都定义为服务,因此注入实体管理器和安全上下文应该没有问题


我个人认为设计本身在这里不是最优的,你最好重构你的代码,让所有应用程序和不同角色使用一个用户(记住,你可以定义许多实体管理器并使用不同的数据库),甚至整合所有数据库并将所有内容存储到一个数据库中,使用acl防止用户查看“错误”内容。

谢谢!在过去的几天里,我一直在做一些研究,在阅读了你的答案后,我意识到我将不得不放弃我想象中的整个想法。然而,您关于使用防火墙服务点的想法非常有趣,值得研究。我可能迟早要做一次代码重构。。。毕竟Symfony官方文档不鼓励单独的应用程序,而是捆绑应用程序。无论如何,非常感谢您的详细解释和非常有用的建议。:)