<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Fischer dot Name &#187; apache</title>
	<atom:link href="http://www.davidfischer.name/tag/apache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidfischer.name</link>
	<description>Some Things to Some People</description>
	<lastBuildDate>Thu, 15 Jul 2010 21:05:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Django authentication and mod_wsgi</title>
		<link>http://www.davidfischer.name/2009/10/django-authentication-and-mod_wsgi/</link>
		<comments>http://www.davidfischer.name/2009/10/django-authentication-and-mod_wsgi/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 17:06:32 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[mod_wsgi]]></category>

		<guid isPermaLink="false">http://www.davidfischer.name/?p=270</guid>
		<description><![CDATA[While I was setting up]]></description>
			<content:encoded><![CDATA[<p>While I was setting up the RPC4Django <a href="https://rpcauth.davidfischer.name/">authenticated demo site</a> (user = pass = rpc4django, self signed certificate), I ran into an interesting problem. There is a <a href="http://docs.djangoproject.com/en/1.0/howto/apache-auth/">well documented</a> way to use the Django auth database for HTTP basic authentication with apache/mod_python, but an authentication handler for mod_wsgi was not built into Django. After some investigation, I found the part of the mod_wsgi documentation on <a href="http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms">Django authentication</a>. However, I was curious why a mod_python authentication handler existed in the Django code line, but no such mod_wsgi handler existed despite the fact that mod_wsgi is now the preferred method of Django production deployment.</p>
<h5>A mod_wsgi authentication handler</h5>
<p>This investigation led me to <a href="http://code.djangoproject.com/ticket/10809">Django ticket #10809</a> which contains a patch for a mod_wsgi authentication handler. I found this interesting and I tried to install it into the demo site. At the time, I hadn&#8217;t even implemented the .wsgi authentication script and I was using an Apache htpasswd file in addition to the Django auth database. However, when I attempted to install the mod_wsgi handler, I ran into a number of issues. Firstly, mod_wsgi does not seem to be able to import a python module from the python path. Therefore, the line: <span style="font-family:monospace">WSGIAuthUserScript  django.contrib.auth.handlers.modwsgi</span> yields:</p>
<pre>Call to fopen() failed for 'django.contrib.auth.handlers.modwsgi'.</pre>
<p> This led me to believe that mod_wsgi literally opens and reads the <span style="font-family:monospace">WSGIAuthUserScript</span>. The problem with this is that <span style="font-family:monospace">DJANGO_SETTINGS_MODULE</span> is not set before that is called and mod_wsgi does not pass environment variables that are set to the auth script. As per the <a href="http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms">documentation</a>:</p>
<blockquote><p>Any configuration defined by SetEnv directives is not passed in the &#8216;environ&#8217; dictionary because doing so would allow users to override the configuration specified in such a way from a &#8216;.htaccess&#8217; file. Configuration should as a result be placed into the script file itself.</p></blockquote>
<p>.<br />
This means that any attempt at a generic mod_wsgi authentication handler is moot since it cannot be configured to connect to the correct project&#8217;s auth database.</p>
<h5>The solution</h5>
<p>The solution is simple and not very gratifying: write an auth script specific for your application. This is what the demo site does now.</p>
<p>httpd.conf:</p>
<pre>&lt;Location "/"&gt;
    AuthType Basic
    AuthName "Login Required"
    Require valid-user
    AuthBasicProvider wsgi
    WSGIAuthUserScript  /path/to/auth.wsgi
&lt;/Location&gt;</pre>
<p>auth.wsgi:</p>
<pre><code class="python">import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'example.settings'

from django.contrib.auth.models import User
from django import db

def check_password(environ, user, password):
    """
    Authenticates apache/mod_wsgi against Django's auth database.
    """

    db.reset_queries() 

    kwargs = {'username': user, 'is_active': True} 

    try:
        # checks that the username is valid
        try:
            user = User.objects.get(**kwargs)
        except User.DoesNotExist:
            return None

        # verifies that the password is valid for the user
        if user.check_password(password):
            return True
        else:
            return False
    finally:
        db.connection.close()</code></pre>
<h5>Update (October 9, 2009)</h5>
<p>After some discussion on <a href="http://code.djangoproject.com/ticket/10809">Django ticket #10809</a> with the author of mod_wsgi, I submitted a <a href="http://code.djangoproject.com/attachment/ticket/10809/modwsgi_auth_handler.2.diff">patch</a> that includes a Django mod_wsgi auth handler. Hopefully it gets accepted soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidfischer.name/2009/10/django-authentication-and-mod_wsgi/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
