Symfony2 如何验证具有两个不同用户名的用户以访问不同的 url
Symfony2 How to authenticate a user with two different user names to access different url
我正在做一个 symfony 项目,我有一个关于用户身份验证的问题希望你能解决,因为我是新手。
我的项目是关于一所学校的,那里有数据库中具有 username
和 password
属性的教师类型用户。用户名由字母 t
后跟个人标识号组成,例如 t48945110
。另外,teachers有一个布尔属性,表示他们中哪一个是校长(只有一个)。
我项目中的安全设置如下:
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 }
通过上面的方法,老师可以通过登录表单访问他的私人部分,但是当我想访问数据库中的导演(具有属性(director=1
)的导演(老师)时遇到的问题).我希望这位老师能够使用另一个用户名访问,但不将其保存在数据库中,只是更改主字母,然后在身份验证中查找老师的正常用户名并检查导演是否将其重定向到/ admin
而不是 /teacher
。比如校长可以通过用户名t48945110访问他作为老师的个人区,也可以通过用户名d48945110
.
访问学校的行政区
这个想法不是创建两个不同的登录表单,而是访问应用程序的所有用户(学生、教师、主任...)。
我不知道是否可以通过事件侦听器或其他方式完成。感谢您的帮助。
我认为你可能把事情复杂化了。我很确定您的主管不想使用不同的用户名登录以进入单独的部分。在不知道更多细节的情况下,我建议将 School\BackendBundle\Entity\Teacher
中的 getRoles()
更改为如下内容:
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');
}
我正在做一个 symfony 项目,我有一个关于用户身份验证的问题希望你能解决,因为我是新手。
我的项目是关于一所学校的,那里有数据库中具有 username
和 password
属性的教师类型用户。用户名由字母 t
后跟个人标识号组成,例如 t48945110
。另外,teachers有一个布尔属性,表示他们中哪一个是校长(只有一个)。
我项目中的安全设置如下:
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 }
通过上面的方法,老师可以通过登录表单访问他的私人部分,但是当我想访问数据库中的导演(具有属性(director=1
)的导演(老师)时遇到的问题).我希望这位老师能够使用另一个用户名访问,但不将其保存在数据库中,只是更改主字母,然后在身份验证中查找老师的正常用户名并检查导演是否将其重定向到/ admin
而不是 /teacher
。比如校长可以通过用户名t48945110访问他作为老师的个人区,也可以通过用户名d48945110
.
这个想法不是创建两个不同的登录表单,而是访问应用程序的所有用户(学生、教师、主任...)。
我不知道是否可以通过事件侦听器或其他方式完成。感谢您的帮助。
我认为你可能把事情复杂化了。我很确定您的主管不想使用不同的用户名登录以进入单独的部分。在不知道更多细节的情况下,我建议将 School\BackendBundle\Entity\Teacher
中的 getRoles()
更改为如下内容:
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');
}