Ntlm/Kerberos authentication in Django

前端 未结 3 1513
半阙折子戏
半阙折子戏 2020-12-08 03:48

I\'m looking for a guide about adding windows authentication support into a django app, particulary OSQA

I\'m aware about http://code.google.com/p/python-ntlm/ And al

相关标签:
3条回答
  • 2020-12-08 03:48

    You can do this using Apache, mod_auth_kerb and REMOTE_USER authentication with Django hosted as mod_wsgi.

    Here is an example of some config we use:

    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>
    

    You then need to setup this:

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

    A couple of caveats to note:

    1. Opera fails completely in our testing; it can't handle the "Negotiate" header
    2. IE works fine if the machine is in the domain, but if it isn't, you get prompted for your password twice - the first time the machine uses "ITSNAME\username" which fails; the second time the bare "username"

    Hope this helps.

    0 讨论(0)
  • 2020-12-08 03:51

    Generally, if you just want authentication against Active Directory, the approach most likely to succeed is to use LDAP authentication against the Active Directory LDAP service. The only trick is that unlike most LDAP servers, Active Directory needs to have an authenticated user (and password). Most folks end up establishing a 'ldap-query' user with and hardcode that user for the query configuration.

    For examples, see http://djangosnippets.org/snippets/501/ and http://www.google.com/search?q=Django+LDAP+authentication

    0 讨论(0)
  • 2020-12-08 03:53

    This might not be that elegant, but it works (import/put into views):

    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
    

    Usage:

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

    I am sure this could be made more elegant as a decorator, and there may be other ways - but I've used it and it works.

    0 讨论(0)
提交回复
热议问题