Django:取消设置用户密码,但仍允许重置密码

vmdwslir  于 2023-03-20  发布在  Go
关注(0)|答案(1)|浏览(86)

我想重置/取消设置我的用户的密码,他们应该被迫使用“密码重置”,并设置一个新的,与新的密码验证器验证。
我找到了Django文档,所以set_unusable_password()不是一个选项,因为之后不允许重置。我发现使用user.password = ''可以工作-用户无法登录,密码重置可以工作。
尽管如此,这个解决方案还是有点笨拙,而且我找不到任何关于这个主题的真实的资源-它的安全性如何,等等?

f1tvaqid

f1tvaqid1#

您说得对,使用User.set_unusable_password后无法重置密码。来自https://docs.djangoproject.com/en/4.0/topics/auth/default/#django.contrib.auth.views.PasswordResetView:
标记为不可用密码的用户(请参阅set_unusable_password())不允许请求密码重置,以防止在使用外部身份验证源(如LDAP)时误用密码。

解决方案1 -覆盖默认Django行为

使用View和Form类来覆盖django.contrib.auth.forms.PasswordResetForm.get_usersdjango.contrib.auth.forms.PasswordResetForm.get_users是Django方法,它获取给定电子邮件地址的User示例。重新实现它而不使用if user.has_usable_password条件,这样你就可以真正利用User.set_unusable_password方法。
这样,您就可以使用Django内部使用的规范,而“无效”的密码永远无法与外部输入匹配。

解决方案2 -无或空字符串

正如您提到的,使用None值或空字符串应该可以工作。我看到的主要缺点是,如果在身份验证逻辑中引入代码错误/回归,它可能会接受空/空白密码并将它们与DB值匹配。攻击者将获得这些帐户的访问权限。
例如,如果用户输入的字符串只包含不允许的字符,验证逻辑接受它,因为它是非空的,然后删除所有无效字符。或者用户输入的字符串只包含空格,这些空格被接受,但后来被删除。在这两种情况下,它都可能导致空字符串,实际上将根据用户的密码测试该字符串,匹配并连接用户。
(and当然,还有很多解决方案可以起作用:))
顺便说一句,关于Django2.1的一个有趣的注解,请参见https://docs.djangoproject.com/en/4.0/releases/2.1/#miscellaneous:
用户.具有可用密码()和密码可用如果密码为None或空字符串,则()函数不再返回False,或者如果密码使用了不在PASSWORD_HASHERS设置中的hasher。这个未记录的行为是Django 1.6中的退化阻止了使用这样密码的用户请求密码重置。审计您的代码以确认您对这些API的使用不依赖于旧的行为。
所以如果你使用Django〈1.6或〉=2.1,你就必须处理它。

相关问题