【问题标题】:Using Django authentication system with existing hashed passwords将 Django 身份验证系统与现有的散列密码一起使用
【发布时间】:2017-06-04 17:15:46
【问题描述】:

我有一个带有用户表的非常旧的 Perl CGI 系统。密码使用crypt 函数存储为计算的哈希值。我希望将系统迁移到 Django,并且我想在使用 Django 表结构时保留用户数据。

一种选择是将所有用户/密码数据复制到auth_user 表并使用自定义身份验证功能,因为我有现有的密码哈希。

我有更好的选择吗?

如果我选择此选项,那么如何实施?

【问题讨论】:

  • 你的方法听起来很合理。如果您无法再次将它们取出,请执行此操作。您还可以添加一个标记来记住哪些密码是旧的,然后在用户登录时逐个升级密码并使用更现代的哈希算法。
  • @GerhardBarnard 非常古老的代码与问题无关。他们不是在问如何翻译它。这个问题是关于过程的,我相信这有点离题。也许它更适合Software Engineering,尽管我在建议时通常是错误的,因为我不常去那个网站。第二部分如何实现肯定是题外话,因为我们不是代码编写服务。
  • @simbabque 我确实考虑过在第一次使用密码时升级密码。 “如何”部分是 Django 特定的。像我需要重写的方法吗?我在这里有一个参考,我可以看看。谢谢
  • @user2125853:“我有更好的选择吗?”你认为什么是“更好的”。您提出的解决方案有什么问题?正如 simbabque 所说,这是相当离题的,因为除了非常广泛的意义之外,您没有编程问题。如果没有原始密码的副本,您将无法默默地“升级”它们。
  • @Borodin 我不是在寻求广义上的选择。我对 Django 不太熟悉。如果 Django 有一个选项(例如使用现有的用户表而不是 auth_user),我正在寻找什么。我很欣赏这里提供的见解。

标签: python django perl


【解决方案1】:

编写自定义身份验证后端的文档位于 Customizing authentication in Django

既然 Borodin 提出要求,并且您可能会发现提供更具体的示例来满足您的要求,我继续编写了一个示例,该示例针对基于 crypt 的文件(例如,htpasswd)进行身份验证。

如果后端在crypt 文件中找到密码匹配的用户,它会查找标准的Django 用户并返回。如果它找不到一个,它会创建一个。显然,您需要决定如何处理实现的实际细节。

./authbackend/__init__.py

import crypt
from django.conf import settings
from django.contrib.auth.models import User

class CryptBackend(object):
    def authenticate(self, request, username=None, password=None):
        crypt_file = getattr(settings, "CRYPT_DB", None)
        if crypt_file is None:
            return None

        password_match = False
        with open(crypt_file,"r") as f:
            for line in f:
                (user, crypted_pass) = line.rstrip().split(":")
                if user == username:
                    password_match = crypt.crypt(password, crypted_pass) == crypted_pass
                    break

        if not password_match:
            return None

        # found a match in our crypt database
        try:
            django_user = User.objects.get(username=username)
        except User.DoesNotExist:
            django_user = User.objects.create_user(username=username, email='', password=password)
            django_user.is_staff = True
            django_user.save()

        return django_user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

新的自定义后端是根据对settings.py 的添加加载的。在我的示例中,我保留了默认的 Django 后端并简单地添加了我的新自定义后端。 Django 按顺序检查它们,因此它将尝试标准的 Django 身份验证,如果这不起作用,则继续使用我的自定义身份验证。 CRYPT_DB 参数是htpasswd 文件的路径。

settings.py

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'authbackend.CryptBackend',
]

CRYPT_DB = '/path/to/your/passwd.file'

为了完整起见,提供上面检查的格式示例 (htpasswd)。

passwd.file

jill:C.1oP2DOot4MY
jack:qJn7lPS/VNssM

【讨论】:

  • 谢谢。这很有帮助。
  • 优秀。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多