2017-04-09 51 views
0

我正在开发一个symfony项目,我在用户身份验证中遇到了一个问题,我希望您解决这个问题,因为我是新手。Symfony2如何验证具有两个不同用户名的用户以访问不同的URL

我的项目是关于一所学校,教师类型的用户在数据库中有usernamepassword属性。用户名由t后跟个人识别号码组成,例如t48945110。另外,教师有一个布尔属性来表明他们哪一个是校长(只有一个)。

是我的项目中的安全设置如下:

Secutiry.yml

security: 

    firewalls: 

    intranet: 
     pattern: ^/ 
     anonymous: ~ 
     provider: teachers 
     form_login: 
      login_path: /login 
      check_path: /login_check 
      # use_referer: true 
      default_target_path: /teacher 
     logout: ~ 

    access_control: 
    - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
    - { path: admin/, roles: ROLE_ADMIN } 
    - { path: /teacher, roles: ROLE_TEACHER } 

    providers: 
     teachers: 
     entity: { class: School\BackendBundle\Entity\Teacher, property: username} 

    encoders: 
     School\BackendBundle\Entity\Teacher: { algorithm: sha512 } 

上述内容,老师可以accerder通过登录表单他的私处,但问题当我想要与导演(在数据库中具有属性(director=1)的教师)访问时,我有。我希望这位老师能够访问另一个用户名,但不能将其保存在数据库中,只需更改主要字母,然后在认证中查找老师的普通用户名,并检查导演是否将其重定向到/ admin而不是/teacher。例如,学校的负责人可以通过用户名t48945110访问他的个人区域作为教师,也可以用用户名d48945110访问学校的管理区域。

这个想法并不是创建两个不同的登录表单,而是访问应用程序的所有用户(学生,教师,导演......)。

我不知道它是否可以通过事件侦听器或其他方式完成。感谢您的帮助。

+0

这似乎对我来说过于复杂。用户名不应该对特定用户具有的角色有任何指示。为什么没有一个位于admin /的管理界面,并且只需通过ACL为老师限制访问权限? – Atan

+0

你好@Atan,谢谢你的回复。在这种情况下,要访问管理员/教师必须先访问私人区域,然后添加一个选项以打开管理部分,对吗?这是我的主要想法,但我不确定是否有任何方法让教师独立访问每个部分,而不使用两种不同的形式,以便他可以这样做。 – Joseph

+0

不,我的意思是使用单一登录表单,并将每个用户(学生,老师,导演)重定向到admin /。然后使用ACL规则根据角色限制用户在管理面板中的访问权限。例如,导演有两个角色:ROLE_TEACHER和ROLE_ADMIN。教师只有ROLE_TEACHER。 – Atan

回答

1

我认为你可能会过于复杂的事情。我很确定你的导演不想用不同的用户名登录进入单独的部分。不知道更多的细节,我建议是改变你的School\BackendBundle\Entity\TeachergetRoles()到这样的事情:

public function getRoles() 
{ 
    $roles = array('ROLE_TEACHER'); 
    if ($this->director == 1) { 
     $roles[] = 'ROLE_DIRECTOR'; 
     $roles[] = 'ROLE_ADMIN'; 
    } 

    return $roles; 
} 

这可能是让用户既具有教师访问他们的安全区域,以及最简单的方法作为导演可以访问管理区域而无需切换帐户。

如果由于某种原因,这不起作用,你可以看看Security Voters。这可能是这个样子:

class TeacherIsDirectorVoter extends Voter 
{ 

    protected function supports($attribute, $subject) 
    { 
     // This voter will always be used 
     return true; 
    } 

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token) 
    { 
     $user = $token->getUser(); 
     // This voter will allow access if the currently logged in user is teacher and is a director 

     return ($user instanceof Teacher && $user->isDirector()); 
    } 
} 

再次,这将给予一个老师谁是没有要求他们登录为不同的用户董事访问。请谨慎选择这位选民,因为它将始终授予对您的网站所有部分使用默认投票策略的director=1的访问权限。有多种方法可以改变这种情况,或者您可以根据提供的属性和被投票的主题添加支票。

我认为您的用例第一个选项(更新角色)可能是最简单的,并且适合您。

如果你想让学生,老师和导演在登录后重定向到不同的页面,你可以做一个小动作。在你的SecurityController(或者你有loginAction的地方)中,创建一个新的targetAction(),成功登录后用作目标。在你的security.yml中,将form_login的default_target_path分配给该路由,而不是/ teacher。这一行动应该可以被所有3个用户组访问。现在只需重定向,基于您的用户拥有的任何角色:

public function targetAAction() 
{ 
    $user = $this->getUser(); 
    if (in_array('ROLE_ADMIN', $user->getRoles())) { 
     return $this->redirectToRoute('intranet_admin_page'); 
    } 
    if (in_array('ROLE_TEACHER', $user->getRoles())) { 
     return $this->redirectToRoute('intranet_teacher_page'); 
    } 

    return $this->redirectToRoute('generic_page_for_users'); 
} 
相关问题