Jov*_*vic 3 session acl symfony
我有多个共享公共实体的symfony2应用程序,但使用不同的数据库设置.每个数据库都有表user,user_role和role.
这里有一个问题:我希望该用户能够app1通过访问www.myproject.com/app1/login和更改URL后登录到仅/app2/使用现有令牌,如果数据库中存在相同的用户(相同的用户名,密码和盐).目前它只检查相同的用户名,你必须同意,非常不方便...app2
我真的不知道什么时候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();
}
}
Run Code Online (Sandbox Code Playgroud)
用户#平等(的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;
Run Code Online (Sandbox Code Playgroud)
}
你的问题让我思考.使用symfony2安全性时,您遇到一个问题:会话有效,意味着用户被认证为匿名用户或真实用户,或者会话无效.
因此,考虑到这一点,我没有看到你的方法按照你的意愿工作,因为让我们说user1登录并使用app1.现在他切换到app2并且不在数据库中,这意味着他不应该访问.现在做什么?使会话无效?这意味着他必须再次登录app1.
如果您要使用子域,则可以将会话绑定到该子域,但这意味着用户必须再次为每个应用程序登录.
还有一个问题:似乎symfony2将用户的id存储到会话中,因此无法访问app1数据库,您无法知道app1数据库中用户的密码和角色是什么,无法检查它.
我猜symfony2的安全性根本就不是针对这种行为.它希望会话与整个应用程序中的同一用户相关.
我不认为symfony2是这里的大问题,而是整个处理用php.让我们想一想没有symfony2我会建议的:
当用户登录时,将用户和角色存储到会话中的特定阵列中,如:
user.app1 = array('username','password',array('role1','role2'))
Run Code Online (Sandbox Code Playgroud)
现在,在对app1的每个请求中,我将检查user.app1是否在会话中并从那里读取角色.如果没有,我会检查user.app2,user.app3等.如果我找不到,请重定向登录.如果我找到一个,我会查询数据库以找到具有相同用户名的用户并比较其他值.如果匹配,将所有内容存储到数据库中.如果没有,请从会话中检查下一个用户.
我查了symfony 安全参考,你有一些扩展点,所以也许你可以在那里工作.在form_login得到了success_handler,所以加入数组作为上述建议应在那里进行会话.防火墙本身具有一定的参数,如request_matcher和entry_point其可用于添加额外的检查像我上面提到的那些.所有都被定义为服务,因此注入实体管理器和安全上下文应该没有问题.
我个人认为设计本身并不是最优的,您可能更好地重构代码,将一个用户用于所有应用程序和不同角色(请记住,您可以定义许多实体管理器并使用不同的数据库),甚至整合所有数据库和将所有内容存储到一个数据库中,使用acl防止用户查看"错误"内容.
| 归档时间: |
|
| 查看次数: |
1988 次 |
| 最近记录: |