tao system of badass pdf= Handling Authentication =

Authentication for Web applications is a tricky business. You would be well advised to read up about the various attacks for cookie-based authentication of web applications first. As a good starting point, see http://www.pdos.lcs.mit.edu/papers/webauth.html

That said, here is a very simple framework for doing Authentication in Albatross. It assumes a login at the start of a session and expires the login after 10 seconds, which forces the user to log in again. The auth is checked on every action, and you don't need toput this stuff into all your application pages, it can be added just once.

First, the application, app.py:

   1 # Some basic auth stuff.  In a real app this would be replaced by something
   2 # much more sophisticated, such as MD5'd cookies.  See, for example,
   3 #
   4 # http://www.pdos.lcs.mit.edu/papers/webauth.html
   5 
   6 import time
   7 
   8 class Auth:
   9         def __init__(self, u, p):
  10                 self.user = u
  11                 self.passwd = p
  12                 self.expire = time.time() + 10 # Lasts 10 seconds
  13 
  14 def check_auth(a):
  15         return a.user == 'foo' and a.passwd == 'bar' and a.expire > time.time()
  16 
  17 from albatross import httpdapp, SimpleApp
  18 
  19 class Login:
  20         name = 'login'
  21 
  22         def page_display(self, ctx):
  23                 ctx.locals.passwd = ''
  24                 if not ctx.has_value('message'):
  25                         ctx.locals.message = ''
  26                 ctx.run_template(self.name + '.html')
  27 
  28         def page_process(self, ctx):
  29                 if ctx.req_equals('login'):
  30                         a = Auth(ctx.locals.user, ctx.locals.passwd)
  31                         if check_auth(a):
  32                                 ctx.locals._auth = a
  33                                 ctx.add_session_vars('_auth')
  34                                 ctx.set_page('start')
  35                         else:
  36                                 # invalid password
  37                                 ctx.locals.message = "Invalid password!"
  38 
  39 
  40 class Start:
  41         name = 'start'
  42 
  43         def page_display(self, ctx):
  44                 ctx.run_template(self.name + '.html')
  45 
  46         def page_process(self, ctx):
  47                 if ctx.req_equals('next'):
  48                         ctx.set_page('next')
  49 
  50 class Next:
  51         name = 'next'
  52 
  53         def page_display(self, ctx):
  54                 ctx.run_template(self.name + '.html')
  55 
  56 
  57 class App(SimpleApp):
  58      def __init__(self, base_url, base_dir):
  59          SimpleApp.__init__(
  60              self,
  61              base_url=base_url,
  62              template_path=base_dir,
  63              start_page='login',
  64              secret='-=secret=-'
  65              )
  66          self.register_page('login', Login())
  67          self.register_page('start', Start())
  68          self.register_page('next', Next())
  69 
  70      def validate_request(self, ctx):
  71         if ctx.locals.__page__ == 'login':
  72                 return 1
  73         print "validate:"
  74         if not hasattr(ctx.locals, '_auth'):
  75                 ctx.set_page('login')
  76                 return 0
  77         if not check_auth(ctx.locals._auth):
  78                 ctx.locals.message = 'Login Expired'
  79                 ctx.set_page('login')
  80                 return 0
  81         return 1
  82 
  83 app = App('/', '.')

Now, three very simple HTML templates. The login page, 'login.html':

<html>
<head></head>
<body>
<h1><al-value expr="message"> Please Log In</h1>
<al-form>
User: <al-input type="text" name="user"/><br>
Password: <al-input type="password" name="passwd"/><br>
<al-input type="submit" name="login" value="Log In"/>
</al-form>
</body>
</html>

The start page, start.html:

<head></head>
<body>
<h1>Start Page</h1>
User: <al-value expr="_auth.user"/> expires <al-value expr="time.ctime(_auth.expire)"/>
<al-form>
<al-input type="submit" name="next" value="go to next page" />
</al-form>
</body>
</html>

And the "next" page, next.html:

<html>
<head></head>
<body>
<h1>Next page Page</h1>
This is the next page.
</body>
</html>

Put these 4 files into a directory, then run al-httpd app.app 8001 and browse localhost:8001.