HTTP Authentication with Twisted.Web2

  1. Overview
  2. Cred
  3. Credential Factories
  4. The HTTPAuthResource

Overview

twisted.web2.auth implements Digest and Basic HTTP Authentication as specified by RFC 2617. This document attempts to describe:

Cred

twisted.cred is a pluggable authentication framework which allows application/protocol developers to easily support multiple authentication types regardless of the backend used. This document assumes some familiarity with cred and suggests you read Cred: Pluggable Authentication and the twisted.cred API Reference for further information. However several of the application specific implementations of objects required by cred are listed below.

from zope.interface import Interface, implements
from twisted.cred import portal

class IHTTPUser(Interface):
    pass

class HTTPUser(object):
    implements(IHTTPUser)

class HTTPAuthRealm(object):
    implements(portal.IRealm)

    def requestAvatar(self, avatarId, mind, *interfaces):
        if IHTTPUser in interfaces:
            return IHTTPUser, HTTPUser()

        raise NotImplementedError("Only IHTTPUser interface is supported")
Listing 1: Cred Setup - ../examples/auth/credsetup.py

Credential Factories

Credential Factories as defined by ICredentialFactory are the heart of HTTP Authentication. Their functions are two-fold:

  1. They provide the challenges and decode the responses from the client, while maintaining state for stateful authentication schemes such as Digest.
  2. They are used to define and determine which authentication schemes should be used during authentication

The ICredentialFactory interface defines the following:

The HTTPAuthResource

The purpose of HTTPAuthResource is to trap both locateChild and renderHTTP and require authentication before allowing requests to pass on to it's wrappedResource. It does this by returning an UnauthorizedResource if the following conditions are not met:

Usage By Example

from twisted.web2 import channel, resource, http, responsecode, server

class ProtectedResource(resource.Resource):
    def render(self, req):
        return http.Response(responsecode.OK,
                             stream=("Hello, you've successfully accessed "
                                     "a protected resource."))

from twisted.web2.auth import digest, basic, wrapper

from twisted.cred.portal import Portal
from twisted.cred import checkers

import credsetup

portal = Portal(credsetup.HTTPAuthRealm())

checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(guest='guest123')

portal.registerChecker(checker)

root = wrapper.HTTPAuthResource(ProtectedResource(),
                                (basic.BasicCredentialFactory('My Realm'),
                                 digest.DigestCredentialFactory('md5',
                                                               'My Realm')),
                                portal, (credsetup.IHTTPUser,))

site = server.Site(root)

# Start up the server
from twisted.application import service, strports
application = service.Application("HTTP Auth Demo")
s = strports.service('tcp:8080', channel.HTTPFactory(site))
s.setServiceParent(application)
Listing 2: Working HTTPAuthResource Example - ../examples/auth/httpauth.tac

This simple example consists of the following application specific components.

  1. A Resource we wish to protect from unauthorized access, in this case it is our ProtectedResource
  2. A portal using our realm from Listing 1, and having a single ICredentialCheckers. In this case a simple checker that stores usernames and passwords in memory and should not be used for anything other than as an example.
  3. A single ICredentialFactory, in this case a DigestCredentialFactory using the md5 algorithm and with a realm of "My Realm"
  4. A sequence of avatar interfaces consisting of our IHTTPUser as defined in Listing 1

Things HTTPAuthResource doesn't do

HTTPAuthResource is provided largely as a lowest common denominator authentication solution. As a result, it has a few limitations:

As a result of these limitations HTTPAuthResource is provided more as an example of how you can work with twisted.web2.auth rather than as a definitive solution.

Index

Version: 0.2.0