tw2.auth

Introduction

tw2.auth is an authentication layer for ToscaWidgets 2 and SQLAlchemy. It aims to provide a “batteries included” authentication system.

Getting started

Note: this requires the experimental tw2.core branch available here: http://github.com/paj28/tw2.core

Add the following to your model:

import sqlalchemy as sa, tw2.auth as twa

class Session(Base):
    __tablename__ = 'session'
    id = sa.Column(sa.String(), primary_key=True)
    user_name = sa.Column(sa.String(), sa.ForeignKey('user.name'))
    user = sa.orm.relationship('User')

class User(Base):
    __tablename__ = 'user'
    name = sa.Column(sa.String(), primary_key=True)
    password = sa.Column(sa.String())
    def __unicode__(self):
        return self.name

twa.config.session_object = Session
twa.config.user_object = User

Your controller should look something like:

import tw2.core as twc, tw2.auth as twa

class Unauth(twc.Directory):
    login = twa.Login()
    # your unprotected widgets go here

class Auth(twc.Directory):
    auth_check = twa.check_session
    # your protected widgets go here
    change_password = twa.ChangePassword()
    logout = twa.Logout()

Your start.py should look something like:

twd.dev_server(host='0.0.0.0', port=80, repoze_tm=True,
    unauth_response=webob.Response(status=302, location='/login'))

To create a user, use interactive Python:

>>> import myapp.model as db, tw2.auth as twa
>>> twa.add_user('admin', 'password')

Inside a controller widget, you can access the current session or user with twa.get_session() and twa.get_user().

Configuration

class tw2.auth.config

Configuration variabels for tw2.auth.

user_object
The SQLAlchemy object for users. This must have a query attribute. (mandatory)
session_object
The SQLAlchemy object for sessions. This must have a query attribute. (mandatory)
user_name_field
The field on the user_object for the user name. (default: ‘name’)
password_field
The field on the user_object for the hashed password. (default: ‘password’)
sid_field
The field on the session_object for the session ID. (default: ‘id’)
user_relation
The name of the relation from session_object to user_object. (default: ‘user’)
hash
The function to hash a password. This takes (password) as an argument and returns the hash using a random salt. (default: pbkdf2.crypt)
verify
The function to verify a password. This takes (password, hash) as arguments and returns True or False. (default: pbkdf2_verify)
post_login
Options to webob.Response to return after a successful login. (default: dict(status=302, location=’/’))
post_logout
Options to webob.Response to return after logout. (default: dict(status=302, location=’/login’))
cookie_name
Name of session cookie (default: ‘tw2.auth’)
cookie_options
Cookie options. For SSL connections, recommended is {‘secure’:True, ‘httponly’:True} (default: {‘httponly’:True})
pwfail_limit
The number of failed logins that will cause account lockout. If this is None, account lockout is disabled. To use this, the user_object must have pwfail_lockout and pwfail_last fields. It is recommended to enable this, to protect against password brute force attacks. (default: None)
pwfail_lockout_time
When pwfail_limit is hit, how long is the lockout? This is in seconds. (default: 60)

Passlib

passlib contains functions for a number of common password hashing schemes. For example, to use Unix DES hashing:

from passlib.hash import des_crypt
twa.config.hash = staticmethod(des_crypt.encrypt)
twa.config.verify = staticmethod(des_crypt.verify)

Future plans

  • CSRF protection
  • Timeout
  • Authorization using groups
  • User registration - potentially with handoff to payment processor
  • User management - needs concept of administrator
  • Forgotten password
  • Password strength validation - ideally, using JavaScript
  • Better logging
  • Fix timing attack on login - leaks user existence
  • Password aging
  • Account lockouts - Captcha
  • Zero shared state mode - cryptographic session id, instead of database table
  • Social login - perhaps using http://pypi.python.org/pypi/ao.social/1.0.2 or http://pypi.python.org/pypi/django-social-auth/ or maybe LoginRadius (managed service)
  • User self-management of sessions; record login time & IP address on session?
  • Stronger authentication, e.g. device fingerprint, integration with Yubikey, EDCC, restrict login to list of IPs

Table Of Contents

This Page