Django中的Ntlm/Kerberos身份验证

Shr*_*ike 13 django windows-authentication

我正在寻找有关在django应用程序中添加Windows身份验证支持的指南,特别是OSQA

我知道http://code.google.com/p/python-ntlm/ 并且还看到了这篇文章:http://erny-rev.blogspot.com/2007/11/ntlm-authentication-in-django .html 但我不是Django-dev,我只是想在Windows环境中部署OSQA(内联网,所以我需要添加Windows身份验证).所以我正在寻找简单的逐步描述.

(我已经设法在Windows上使用SQL Server部署OSQA站点并且它正在运行)

更新:
我不仅要获得针对AD的身份验证,还要避免在IE中使用类似SSO的行为.当用户在IE中访问我的基于django的站点时,它会自动通过其域帐户进行身份验证.

Rea*_*ist 12

你可以使用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>
Run Code Online (Sandbox Code Playgroud)

然后你需要设置这个:

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

需要注意的几点需要注意:

  1. Opera在我们的测试中完全失败; 它无法处理"Negotiate"标题
  2. 如果机器在域中,IE工作正常,但如果不是,则会提示您输入密码两次 - 第一次机器使用"ITSNAME\username"失败; 第二次裸露的"用户名"

希望这可以帮助.


Dan*_*ple 6

这可能不是那么优雅,但它可以工作(导入/放入视图):

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
Run Code Online (Sandbox Code Playgroud)

用法:

def my_view(request):
    username, response = ntlm_auth(request)
    if response:
        return response
Run Code Online (Sandbox Code Playgroud)

我确信这可以作为装饰者变得更优雅,并且可能有其他方式 - 但我已经使用它并且它有效.

  • 实际的身份验证在哪里发生?这看起来就像它只接受浏览器响应(这可能是欺骗的?)。 (2认同)

Cra*_*der 5

通常,如果您只想对Active Directory进行身份验证,则最有可能成功的方法是对Active Directory LDAP服务使用LDAP身份验证.唯一的技巧是,与大多数LDAP服务器不同,Active Directory需要拥有经过身份验证的用户(和密码).大多数人最终建立了一个'ldap-query'用户,并为该查询配置硬编码该用户.

有关示例,请参阅http://djangosnippets.org/snippets/501/http://www.google.com/search?q=Django+LDAP+authentication