<?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; authentication</title>
	<atom:link href="http://www.davidfischer.name/tag/authentication/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>Updates April 2010 Edition</title>
		<link>http://www.davidfischer.name/2010/04/updates-april-2010-edition/</link>
		<comments>http://www.davidfischer.name/2010/04/updates-april-2010-edition/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 16:57:28 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[django-pyodbc]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[mod_wsgi]]></category>
		<category><![CDATA[rpc4django]]></category>
		<category><![CDATA[sphinx]]></category>

		<guid isPermaLink="false">http://www.davidfischer.name/?p=503</guid>
		<description><![CDATA[Django tickets There&#8217;s been only]]></description>
			<content:encoded><![CDATA[<h5>Django tickets</h5>
<p>There&#8217;s been only a little movement on the ticket (<a href="http://code.djangoproject.com/ticket/13101">#13101</a>) I patched for 1.2. However, there&#8217;s been some new developments on the ticket (<a href="http://code.djangoproject.com/ticket/10809">#10809</a>) I patched regarding authentication with mod_wsgi. There&#8217;s been a suggestion to add group based authorization to Django&#8217;s mod_wsgi auth handler. There&#8217;s still some debate as to whether to use Django groups or Django permissions. </p>
<h5>django-pyodbc is dead?</h5>
<p>In a <a href="http://www.davidfischer.name/2010/03/updates-march-2010-edition/">previous post</a>, I talked about getting involved in <a href="http://code.google.com/p/django-pyodbc/">django-pyodbc</a> development. We are using django-pyodbc at work but the project is languishing a little bit. The project has never had a formal release, the documentation (other than source documentation) is a little light, and despite patches being submitted to get the code in shape for Django&#8217;s upcoming 1.2 release, nothing has been checked in by the developers. In fact, there&#8217;s been nothing on the project from the developers since January. I emailed the developers a few days ago offering to help and I haven&#8217;t heard anything back yet. I&#8217;d much rather keep the project together, but if I continue to get nothing I will probably branch the code line and begin development and maintenance. I&#8217;m not looking forward to having to find a Windows box on which to setup multiple versions of SQL Server but I&#8217;m hoping to be able to virtualize it.</p>
<p><strong>Edit (June 23, 2010):</strong> The developers have gotten involved again and I killed my fork of the project.</p>
<h5>RPC4Django updates</h5>
<p>I&#8217;m planning to put some effort into RPC4Django this weekend and make a release in the next week or two. The main features I&#8217;m looking at is the existing blueprint in Launchpad to <a href="https://blueprints.launchpad.net/rpc4django/+spec/handle-authentication">handle authentication</a> out of the box. Other than that, I got a little feedback on the HTTP access control functionality back in January that I need to test. I also plan to rip out the existing documentation and go to a <a href="http://sphinx.pocoo.org/">Sphinx</a> based system. We&#8217;ve been using Sphinx at work and I&#8217;ve been very impressed with its capabilities.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidfischer.name/2010/04/updates-april-2010-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RPC4Django v0.1.6 Feature Requests</title>
		<link>http://www.davidfischer.name/2009/12/rpc4django-0-1-6-feature-requests/</link>
		<comments>http://www.davidfischer.name/2009/12/rpc4django-0-1-6-feature-requests/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 18:42:21 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[rpc4django]]></category>

		<guid isPermaLink="false">http://www.davidfischer.name/?p=338</guid>
		<description><![CDATA[A number of feature requests]]></description>
			<content:encoded><![CDATA[<p>A number of feature requests have come in and I am going to outline what I&#8217;m going to try to get done. I hope to put out a release next week (I&#8217;ve said that before), but that greatly depends on what features go into it. </p>
<h5>Access to HttpRequest</h5>
<p>One user submitted feature that seems particularly useful is the ability to access variables and data in the <a href="http://docs.djangoproject.com/en/dev/ref/request-response/#ref-request-response">HttpRequest</a> that dispatches the RPC method. For example:</p>
<pre><code class="python">@rpcmethod(permission='myproject.mypermission')
def testmethod(a, b, c):
    # Do something
</code></pre>
<p>This RPC method will be authenticated, but it cannot tell who the user is for example. It does not have the ability to read the <span style="font-family:monospace">REMOTE_USER</span> variable. This would be particularly useful if the RPC method was submitting data and needed to know who the submitter was. To rectify this situation, I am proposing sending the HttpRequest object as a keyword argument:</p>
<pre><code class="python">@rpcmethod(permission='myproject.mypermission')
def testmethod(a, b, c, **kwargs):
    if 'REMOTE_USER' in kwargs['request'].META:
        user = request.kwargs.META['REMOTE_USER']
        # Do something
</code></pre>
<p>Methods that need access can accept all the additional keyword arguments and methods that don&#8217;t care can be written as normal and do not need to change.</p>
<h5>Work with the cross site request forgery framework</h5>
<p>Django has added a new module to protect against cross site request forgery (<a href="http://docs.djangoproject.com/en/dev/ref/contrib/csrf/">CSRF</a>). Unfortunately, if a user adds the <span style="font-family:monospace">django.middleware.csrf.CsrfViewMiddleware</span> to their project, it will break RPC4Django. CSRF protection works by ensuring that all GET requests are side-effect free and then adding a little bit of random data (the CSRF token) to every form that submits via POST. The server can then verify that the correct random data was POSTed and this ensures that the form was submitted from your site and not some remote site.</p>
<p>Unfortunately, RPC is usually intended to be used in a cross site fashion. The fix is relatively painless, but requires some adversarial testing to make it work under Django 1.0, Django 1.1 and Django 1.2. The code (views.py) will look something like this:</p>
<pre><code class="python">try:
    # Django 1.2
    from django.views.decorators.csrf import csrf_exempt
except ImportError:
    try:
        # Django 1.1
        from django.contrib.csrf.middleware import csrf_exempt
    except ImportError:
        # Django 1.0
        csrf_exempt = None

if csrf_exempt is not None:
    csrf_exempt(serve_rpc_request)
</code></pre>
<p>I need to test it out very thoroughly and on a number of setups, but I think this code should do it.</p>
<h5>HTTP access control</h5>
<p>Usually the Javascript <span style="font-family:monospace">XmlHttpRequest</span> object is subject to the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a>. This is a security measure that ensures that Javascript will only access data from the same domain, protocol and port as the initial request. There have always been hacks to get around this and the browser vendors are finally <a href="https://developer.mozilla.org/en/HTTP_access_control">providing</a> a uniform, secure way around.</p>
<p>Basically, RPC4Django will need to respond to an HTTP <strong>OPTIONS</strong> request with the header <span style="font-family:monospace">Access-Control-Allow-Origin</span> specifying what domains are allowed to send requests. Both allowing HTTP access control and which domains are allowed will be options in <span style="font-family:monospace">settings.py</span>.</p>
<h5>Patches and feature requests</h5>
<p>As always, I am happy to accept patches, but this is what I&#8217;ll be working on next week. Please let me know if there are any other important features that you would like to see in RPC4Django.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidfischer.name/2009/12/rpc4django-0-1-6-feature-requests/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Using Django for Intranet Applications</title>
		<link>http://www.davidfischer.name/2009/10/using-django-for-intranet-applications/</link>
		<comments>http://www.davidfischer.name/2009/10/using-django-for-intranet-applications/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 23:51:42 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[intranet]]></category>

		<guid isPermaLink="false">http://www.davidfischer.name/?p=295</guid>
		<description><![CDATA[One thing I end up]]></description>
			<content:encoded><![CDATA[<p>One thing I end up doing quite a bit of at work is developing custom web applications that sit on the company intranet. These aren&#8217;t your basic timecard application or company web portal. Instead, these customized applications do everything from reports and dashboards from our bug tracking software to providing a web service API to our test case management solution. This post is about chronicling some of our forays into intranet apps.</p>
<h5>Every intranet app needs authentication</h5>
<p>If your company is anything like mine, you have a huge Active Directory system and your webservers are protected by single-sign-on (SSO). Django plugs into that nicely with the <a href="http://docs.djangoproject.com/en/dev/howto/auth-remote-user/">RemoteUserMiddleware</a> so that users don&#8217;t have to remember Yet Another Password for your app. My password to our off the shelf commercial bug tracking software is still &#8220;welcome&#8221; and my password to our &#8220;Agile&#8221; project and task tracker is &#8220;test&#8221;. I&#8217;m already on the corporate intranet. Why should I have to authenticate twice? With Django and RemoteUserMiddleware, your users are automatically logged in if they&#8217;re authenticated. It seems relatively trivial, but it greatly enhances the user experience to not have to remember the password to the /admin site. </p>
<h5>Who needs /admin</h5>
<p>It seems that virtually every application has some sort of need for admin functionality. We used to deploy <a href="http://www.phpmyadmin.net">phpMyAdmin</a> on most of our web hosts to administer our content. It was dove hunting with a bazooka. There was little fine grained control and we ran into the same issue of re-authenticating to access the admin site. Now an admin site is not unique to Django and it exists in virtually every major web framework in every major language. This point can be taken as an overwhelming endorsement of using some framework over using no framework at all. However, Django&#8217;s <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/">admin site</a> is easy and very customizable in case you need to pretty up your admin site because it will be accessed by a wider audience.</p>
<h5>Intranet apps have a way of becoming internet apps</h5>
<p>You never know management decides some piece of software that was never intended to be used externally suddenly is a must have for some outside group and it needs to be internationalized (into Japanese?!). Suddenly, all the code has to go through open source compliance, export compliance, code scans, and due to licensing restrictions management doesn&#8217;t want to ship with MySQL. Unfortunately, that software was written in Java and PHP with no framework and quite a few open source libraries that we couldn&#8217;t ship. The transition was much more painful than if we would have just used Django from the start. </p>
<h5>Merging and splitting apps</h5>
<p>I&#8217;ve released and deployed a number of web applications, but the real nightmare comes when apps are merged together or one app is broken apart. This is where Python&#8217;s packaging and the Django <a href="http://www.davidfischer.name/2009/07/packaging-and-sharing-django-applications/">concept of splitting your project into multiple individual apps</a> really shines. I&#8217;ve run into this from a couple of different sides. I&#8217;ve had to take multiple PHP applications and merge them together into a single deployment. There was a huge mess with including common code and the solutions aren&#8217;t great. You&#8217;re either messing with <a href="http://us.php.net/manual/en/ini.core.php#ini.include-path">include_dir</a> in php.ini &#8212; a huge nightmare when managing multiple deployments with different includes, or you&#8217;re stuck modifying every include statement to pickup libraries from a common location. Splitting apps up runs into similar issues. Packaging separable components into different apps used by your project really is the way to go and Django works with this very well.</p>
<p>I&#8217;ve developed web apps in Java, Perl and PHP and by far I&#8217;ve been happiest with Python and Django. There are other great frameworks out there for these languages and using them could definitely help alleviate some of these issues, but the Django solution fits together better than anything I&#8217;ve seen from Struts, CodeIgniter or one of the dozens of other frameworks out there. For me, there has to be a pretty compelling argument not to do new apps with Django.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidfischer.name/2009/10/using-django-for-intranet-applications/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<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>
		<item>
		<title>RPC and Authentication</title>
		<link>http://www.davidfischer.name/2009/09/rpc-and-authentication/</link>
		<comments>http://www.davidfischer.name/2009/09/rpc-and-authentication/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 05:04:45 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[amazons3]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[authorization]]></category>
		<category><![CDATA[rpc4django]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[webservices]]></category>

		<guid isPermaLink="false">http://www.davidfischer.name/?p=239</guid>
		<description><![CDATA[I&#8217;m working on adding support]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on adding support for authenticated service calls to <a href="http://www.davidfischer.name/rpc4django/">RPC4Django</a> built on top of Django&#8217;s <a href="http://docs.djangoproject.com/en/dev/topics/auth">user authentication</a>. While doing this, I took a brief look around at how other projects implemented authentication for XMLRPC or JSONRPC. Without exception, they all implemented it such that the username and password was part of the RPC call like so:</p>
<pre><code class="python">from django.contrib.auth import authenticate

def myAuthenticatedMethod(user, password, otherparams):
    # authenticate user
    user = authenticate(username=user, password=password)

    # verify the user is valid and has the appropriate permissions
    # perform method actions</code></pre>
<p>Some of them abstracted the actual username and password checking into a decorator, but in the end, the RPC call had the username and password in the parameters. It seemed bulky and out of place. This led to an analysis about authentication and authorization and what should be handled where. As a little spoiler, I don&#8217;t like the idea of sending the username and password in the RPC parameters one bit.</p>
<h5>Authentication &#038; Authorization</h5>
<p>In applications, authentication is the process that confirms the identity of the user. Usually this takes the form of a login form, HTTP basic authentication,  or something similar. Authorization is the process to determine whether the user has sufficient privileges to perform the specified action. This takes the form of permission checks based on the authenticated user. Therefore, authentication must come before authorization. </p>
<p>Fortunately, Django&#8217;s user authentication helps with both authentication and authorization. The <code><a href="http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.authenticate">authenticate</a></code> method checks a username and password against the set of Django users and gets the user object if everything goes well. Once this user object is retrieved, permissions can be checked using the <code><a href="http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.User.has_perm">has_perm</a></code> method. Django has a pretty easy way to create new permissions based on your application&#8217;s logic. Permissions have to be checked at the specific method level since permissions are closely tied to the application logic. I like the idea of abstracting much of it into a decorator though. The only remaining question is: where does the username and password come from?</p>
<h5>An Example from the Real World</h5>
<p>Why should every RPC method need to be specially written to accept the login credentials and authenticate the user? This makes the method only usable as an RPC method and not useful at all to the rest of the project which is bad for code reuse. <a href="http://aws.amazon.com/s3/">Amazon s3</a>, a commercial web service for storing files, is a perfect example of the proper way to authenticate and authorize users. With s3, the login information is contained in the HTTP header in a manner similar to HTTP basic authentication and in this way the request can be rejected earlier based on login credentials before the request even routes to the proper method requested. Permission checking, seeing whether the user is allowed to store new files for example, still needs to be done at the method level but at least the identity of the user is known.</p>
<h5>Implementation and Demo</h5>
<p>For RPC4Django, I&#8217;m proposing that authentication be handled at a higher level &#8212; with basic HTTP authentication for example. To illustrate this, I set up an https RPC4Django <a href="https://rpcauth.davidfischer.name/">demo site</a> that requires a username and password (rpc4django/rpc4django). The demo site requires that you accept a self-signed certificate. Using python, it is possible to send authenticated requests like so:</p>
<pre><code class="python">from xmlrpclib import ServerProxy
s = ServerProxy('https://rpc4django:rpc4django@rpcauth.davidfischer.name/')
s.system.listMethods()</code></pre>
<p>The next step is to modify RPC4Django to actually be able to specify permissions for specific methods and to actually log in the users. Expect a release this week.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidfischer.name/2009/09/rpc-and-authentication/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
