Login

Custom mod_python AuthenHandler

Author:
aeby
Posted:
August 12, 2007
Language:
Python
Version:
.96
Score:
1 (after 3 ratings)

This handler is useful if you serve static/media files directly from Apache only to authenticated users. It checks if a user is not anonymous (and therefore logged in) and redirects to the login site if needed. The following apache config activates the handler:

<Location "/site_media/company1">
    #SetHandler None ##Uncomment if you serve static files in the same virtual host
    PythonOption DJANGO_SETTINGS_MODULE mysite.settings
    PythonAuthenHandler mysite.myhandler
    PythonPath "['/path/to/project'] + sys.path"
    Require valid-user
</Location>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from mod_python import apache
from mod_python import util
import os

def authenhandler(req, **kwargs):
    """
    Authentication handler that checks if user is logged in
    """

    # mod_python fakes the environ, and thus doesn't process SetEnv.  This fixes
    # that so that the following import works
    os.environ.update(req.subprocess_env)
    
    # check for PythonOptions
    _str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes')
    
    options = req.get_options()
    settings_module = options.get('DJANGO_SETTINGS_MODULE', None)
    if settings_module:
        os.environ['DJANGO_SETTINGS_MODULE'] = settings_module
        
    from django import db
    from django.conf import settings
    from django.core.handlers.modpython import ModPythonRequest
    from django.contrib.auth.middleware import LazyUser
    from django.contrib.sessions.middleware import SessionWrapper
    
    db.reset_queries()

    request = ModPythonRequest(req)
    
    # set session to request    
    request.session = SessionWrapper(request.COOKIES.get(settings.SESSION_COOKIE_NAME, None))
    
    # set user to request
    request.__class__.user = LazyUser()
    
    require_login_path = getattr(settings, 'REQUIRE_LOGIN_PATH', '/accounts/login/')
    
    try:
        if request.path != require_login_path and request.user.is_anonymous():
            util.redirect(req, str('%s?next=%s' % (require_login_path, request.path)))
        else:
            req.user = str(request.user)
            return apache.OK
    except:
        return apache.HTTP_UNAUTHORIZED
    finally:
        db.connection.close()

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

LuckiDog (on October 3, 2007):

This doesn't quite work for me. Content type is getting set to "text/plain" for all my files. Not so good for jpg/gif/pdf etc...

Not sure what's triggering this behavior. I suspected that creating the ModPythonRequest could be the problem, and coded around that, but no luck.

#

LuckiDog (on October 3, 2007):

Ok, setting

AuthType Basic AuthName 'What ever'

Gets the correct content displayed, but the http auth window still pops up - it's contents are ignored of course.

#

LuckiDog (on October 3, 2007):

Ok.. got a real solution here. Use this config:

<Location "/media/whatever"> ##Uncomment if you serve static files in the same virtual host #SetHandler None

PythonOption DJANGO_SETTINGS_MODULE mysite.settings

PythonHeaderParserHandler mysite.handlers
PythonPath "['/path/to/project'] + sys.path"

</Location>

and name the function "headerparserhandler"

Since it's not basic auth, we apperently don't want to use AuthenHandler.

#

LuckiDog (on October 3, 2007):

Ok... one more comment. you need to add another try to correspond with the "finally:"

try: try: Blah blah blah return apache.OK except: return apache.HTTP_UNAUTHORIZED finally: db.connection.close()

#

Please login first before commenting.