Подтвердить что ты не робот

Проверка подлинности Ntlm/Kerberos в Django

Я ищу руководство по добавлению поддержки проверки подлинности Windows в приложение django, особенно OSQA

Я знаю о http://code.google.com/p/python-ntlm/ А также увидел этот пост: http://erny-rev.blogspot.com/2007/11/ntlm-authentication-in-django.html Но я не Django-dev, я просто хочу развернуть OSQA в среде Windows (интрасеть, поэтому мне нужно добавить проверку подлинности Windows). Поэтому я ищу простое пошаговое описание.

(мне удалось развернуть сайт OSQA на окнах с SQL Server и работать)

UPDATE:
Я хотел бы получить не просто auth против AD, а SSO-подобного поведения в IE. Поскольку пользователь получает доступ к моему сайту на основе Django в IE, он автоматически аутентифицируется с его учетной записью домена.

4b9b3361

Ответ 1

Вы можете сделать это, используя аутентификацию Apache, mod_auth_kerb и REMOTE_USER с Django, размещенным как mod_wsgi.

Вот пример некоторой конфигурации, которую мы используем:

WSGIDaemonProcess myapp user=myapp group=myapp processes=5 threads=1
WSGIProcessGroup myapp
WSGIScriptAlias /myapp /home/wolapp/code/wolapp.wsgi
<VirtualHost ...>
    <Location /myapp>
            AuthType                Kerberos
            AuthName                "Domain Login"
            KrbMethodNegotiate      On
            KrbMethodK5Passwd       On
            KrbAuthRealms           YOUR.DOMAIN
            Krb5Keytab              /etc/krb5.keytab
            KrbServiceName          HTTP/server.your.domain
            require                 valid-user
    </Location>
</VirtualHost>

Затем вам нужно настроить это:

http://docs.djangoproject.com/en/dev/howto/auth-remote-user/

Несколько предостережений:

  • Opera полностью не работает в нашем тестировании; он не может обрабатывать заголовок "Negotiate"
  • IE работает отлично, если машина находится в домене, но если это не так, вы дважды запрашиваете свой пароль - при первом запуске машины "ITSNAME\username", который не работает; второй раз голый "имя пользователя"

Надеюсь, что это поможет.

Ответ 2

Это может быть не так элегантно, но он работает (импортируется/помещается в представления):

import base64


def get_msg_str(msg,start):
    msg_len, _, msg_off = struct.unpack("<HHH", msg[start:start + 6])
    return msg[msg_off:msg_off + msg_len].replace("\0", '')


def ntlm_auth(request):
    """Goes through ntlm stages...
    Return user_name, response.
    While response is not none, keep sending it.
    Then use the user.
    """
    username = None
    response = None

    auth = request.META.get('HTTP_AUTHORIZATION')
    if not auth:
        response = HttpResponse(status=401)
        response['WWW-Authenticate'] = "NTLM"
    elif auth[:4] == "NTLM":
        msg = base64.b64decode(auth[4:])
        #  print repr(msg)
        ntlm_fmt = "<8sb" #string, length 8, 4 - op
        NLTM_SIG = "NTLMSSP\0"
        signature, op = struct.unpack(ntlm_fmt, msg[:9])
        if signature != NLTM_SIG:
            print "error header not recognized"
        else:
            print "recognized"
            # print signature, op
            # print repr(msg)
            if op == 1:
                out_msg_fmt = ntlm_fmt + "2I4B2Q2H"
                out_msg = struct.pack(out_msg_fmt,
                    NLTM_SIG, #Signature
                    2, #Op
                    0, #target name len
                    0, #target len off
                    1, 2, 0x81, 1, #flags
                    0, #challenge
                    0, #context
                    0, #target info len
                    0x30, #target info offset
                )

                response = HttpResponse(status=401)
                response['WWW-Authenticate'] = "NTLM " + base64.b64encode(out_msg).strip()
            elif op == 3:
                username = get_msg_str(msg, 36)

    return username, response

Использование:

def my_view(request):
    username, response = ntlm_auth(request)
    if response:
        return response

Я уверен, что это можно сделать более элегантным как декоратор, и могут быть другие способы, но я использовал его, и он работает.

Ответ 3

В общем случае, если вам просто нужна аутентификация в Active Directory, наиболее вероятным для этого способом является использование аутентификации LDAP для службы LDAP Active Directory. Единственный трюк заключается в том, что, в отличие от большинства серверов LDAP, Active Directory должен иметь аутентифицированного пользователя (и пароль). Большинство людей в конечном итоге устанавливают пользователя "ldap-query" и жесткого кода этого пользователя для конфигурации запроса.

Примеры см. в http://djangosnippets.org/snippets/501/ и http://www.google.com/search?q=Django+LDAP+authentication