问题描述
在Symfony 5项目中,我有一个 User 实体,其中两个字段均为“ 密码”(已散列)和“ smsCode ”(普通)。
创建帐户时,首先会使用smsCode进行身份验证,直到用户以后设置密码为止(然后我们在不为空的情况下使用该密码,并忽略smsCode)。
我要实现的目标:通过HTTP Basic进行身份验证,但使用smsCode而不是哈希密码。
我设法通过编辑LoginFormAuthenticator上的checkCredentials()
函数来使用表单登录进行此工作:我可以使用我的SMS代码而不是密码通过表单登录。
但是,当我尝试通过HTTP Basic进行身份验证时,将调用DaoAuthenticationProvider.php上的checkAuthentication()
函数,并且此类使用$user->getPassword()
获取密码。有什么方法可以覆盖/扩展此checkAuthentication()
函数,以便我可以首先检查普通的smsCode($user->getSmsCode()
)而不是哈希密码?
#security:
encoders:
App\Entity\User:
algorithm: auto
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
# profiler (dev only)
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
lazy: true
provider: app_user_provider
http_basic: true
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: app_logout
我尝试编辑getPassword()
函数以首先检查smsCode:
public function getPassword(): string
{
if (!empty($this->smsCode)) {
return (string) $this->smsCode;
} else {
return (string) $this->password;
}
}
不幸的是,由于密码是散列的,因此它一直在验证失败,因为它正在寻找smsCode(DaoAuthenticationProvider.php中的函数isPasswordValid()
)的散列版本
(当使用密码而不是SMS代码时,身份验证非常有效)
解决方法
为了保持逻辑(和代码)流程相同,当前您已经将哈希密码作为目标变量,因此,在生成SMS代码时,可以将SMS代码的hahed版本添加到数据库中。用作替换哈希密码值的对象。
然后,在使用HTTPAuth时,您可以简单地引用此“ hashedSMS”字符串而不是哈希密码字符串,以进行比较。
注意:出于安全考虑; SMScode应该具有足够的熵,因此应该足够长-通常超过8个字符。
通常,在当前的生态系统中,SMS代码比密码更短,更简单,并且由于其传输方法(通过手机短信)非常不安全,并且可以进行窃听和拦截,因此使该代码成为了薄弱环节。应用程序的安全性。
这种身份验证方法只能作为最后的手段。
- 也作为最后的注释;尽管不是 2FA,并且尽管这种身份验证形式容易受到滥用和损害,但许多网站仍将SMS代码用作“双重身份验证”方法。
实际上,大多数大型网络公司只是简单地要求您提供移动电话号码的“安全性”表面贴,实际上只是收集电话号码以与您的帐户联系以用于自己的跟踪和营销目的,同时声称这是“更好的安全性” “。