gpt4 book ai didi

session - Symfony2 跨多个应用程序共享用户

转载 作者:行者123 更新时间:2023-12-02 18:43:40 25 4
gpt4 key购买 nike

我有多个 symfony2 应用程序,它们共享公共(public)实体,但使用不同的数据库设置。每个数据库都有表 useruser_rolerole

问题是:我希望该用户能够通过访问 www.myproject.com/app1/login 并将 URL 更改为 来登录 app1 code>/app2/ 仅当 app2 的数据库中存在相同的用户(相同的用户名、密码和盐)时才使用现有 token 。 目前它仅检查相同的用户名,您必须同意,这非常不方便......

我无法真正看到 refreshUser() 何时被调用...:-/

所有应用都使用相同的UserRole实体以及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();
}
}

User#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;

}

最佳答案

你的问题让我思考。在使用 symfony2 安全性时,你遇到一个问题:要么 session 有效,这意味着用户被验证为匿名或真实用户,要么 session 无效。

因此,考虑到这一点,我认为您的方法无法按您希望的方式工作,因为假设 user1 登录并正在使用 app1。现在他切换到 app2 并且不在数据库中,这意味着他不应该具有访问权限。现在做什么?使 session 无效?这意味着他必须在 app1 中再次登录。

如果您要使用子域,则可以将 session 绑定(bind)到该子域,但这意味着用户必须为每个应用程序重新登录。

还有一个问题:好像symfony2将用户的id存储到 session 中,因此如果不访问app1数据库,您无法知道app1数据库中用户的密码和角色是什么,也无法检查为了它。

我猜 symfony2 的安全性根本就不是为了这种行为而设计的。它期望 session 与整个应用程序中的同一用户相关。

我不认为 symfony2 是这里的大问题,而是 php 的整体处理。让我们想一下如果没有 symfony2 我会建议什么:

当用户登录时,将用户和角色存储到 session 中的特定数组中,例如:

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

现在,在对 app1 的每个请求中,我都会检查 user.app1 是否在 session 中并从那里读取角色。如果没有,我会检查 user.app2、user.app3 等。如果找不到,请重定向到登录。如果找到一个,我将查询数据库以查找具有相同用户名的用户并比较其他值。如果匹配,则将所有内容存储到数据库中。如果没有,请检查 session 中的下一个用户。

我查了symfony security reference ,并且您有一些扩展点,所以也许您可以从那里开始工作。 form_login 有一个 success_handler,因此应该按照上面的建议将数组添加到 session 中。防火墙本身有一些参数,例如 request_matcherentry_point,它们可用于添加额外的检查,如我上面提到的那些。所有这些都被定义为服务,因此注入(inject)实体管理器和安全上下文应该没有问题。

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

关于session - Symfony2 跨多个应用程序共享用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9672560/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com