使用不同于密码的字段进行HTTP Basic身份验证



在Symfony 5项目中,我有一个具有两个字段的User实体">密码";(散列(和">smsCode";(普通(。

创建帐户时,首先使用smsCode进行身份验证,直到用户稍后设置密码(然后我们在不为空时使用密码并忽略smsCode(。

我试图实现的是:通过HTTPBasic进行身份验证,但使用smsCode而不是散列密码。

我通过编辑LoginFormAuthenticator上的checkCredentials()功能,使用表单登录成功了:我可以使用我的短信代码而不是密码通过表单登录。

但是,当我尝试通过HTTPBasic进行身份验证时,会调用DaoAuthenticationProvider.php上的checkAuthentication()函数,该类使用$user->getPassword()获取密码。有没有什么方法可以覆盖/扩展这个checkAuthentication()函数,这样我就可以首先检查纯smsCode($user->getSmsCode()(而不是散列密码?

#security:
encoders:
AppEntityUser:
algorithm: auto
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: AppEntityUser
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:
- AppSecurityLoginFormAuthenticator
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代码的散列版本添加到数据库中,用作散列密码值的替换。

然后当使用HTTPAuth时,你可以简单地引用这个";hashedSMS";字符串,而不是散列后的密码字符串。


注意:为了安全;SMS代码应该具有足够的熵,因此应该足够长——通常长于8个字符。

在当前的生态系统中,SMS代码通常比密码更短、更不复杂,而且由于它们的传输方法(通过手机短信(极不安全,而且对窃听和拦截非常开放,这使得代码成为应用程序安全的薄弱环节。

这种身份验证方法只能作为最后手段。

  • 同时作为最后的旁注;许多网站使用SMS代码作为"短信";双因素认证";方法,尽管这种不是2FA,尽管这种形式的身份验证很容易被滥用和泄露

    事实上,大多数大型网络企业只需将询问您的手机号码作为";安全性";实际上,只是为了收集一个电话号码来连接你的账户,用于他们自己的跟踪和营销目的,同时声称这是某种形式的";更好的安全性">

最新更新