1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# (c) 2005 Clark C. Evans
# This module is part of the Python Paste Project and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
# This code was written with funding by http://prometheusresearch.com
"""
Basic HTTP/1.0 Authentication
This module implements ``Basic`` authentication as described in
HTTP/1.0 specification [1]_ . Do not use this module unless you
are using SSL or need to work with very out-dated clients, instead
use ``digest`` authentication.
>>> from paste.wsgilib import dump_environ
>>> from paste.util.httpserver import serve
>>> # from paste.auth.basic import AuthBasicHandler
>>> realm = 'Test Realm'
>>> def authfunc(username, password):
... return username == password
>>> serve(AuthBasicHandler(dump_environ, realm, authfunc))
serving on...
.. [1] http://www.w3.org/Protocols/HTTP/1.0/draft-ietf-http-spec.html#BasicAA
"""
from paste.httpexceptions import HTTPUnauthorized
from paste.httpheaders import *
class AuthBasicAuthenticator:
"""
implements ``Basic`` authentication details
"""
type = 'basic'
def __init__(self, realm, authfunc):
self.realm = realm
self.authfunc = authfunc
def build_authentication(self):
head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
return HTTPUnauthorized(headers=head)
def authenticate(self, environ):
authorization = AUTHORIZATION(environ)
if not authorization:
return self.build_authentication()
(authmeth, auth) = authorization.split(' ',1)
if 'basic' != authmeth.lower():
return self.build_authentication()
auth = auth.strip().decode('base64')
username, password = auth.split(':',1)
if self.authfunc(username, password):
return username
return self.build_authentication()
__call__ = authenticate
class AuthBasicHandler:
"""
HTTP/1.0 ``Basic`` authentication middleware
Parameters:
``application``
The application object is called only upon successful
authentication, and can assume ``environ['REMOTE_USER']``
is set. If the ``REMOTE_USER`` is already set, this
middleware is simply pass-through.
``realm``
This is a identifier for the authority that is requesting
authorization. It is shown to the user and should be unique
within the domain it is being used.
``authfunc``
This is a mandatory user-defined function which takes a
``username`` and ``password`` for its first and second
arguments respectively. It should return ``True`` if
the user is authenticated.
"""
def __init__(self, application, realm, authfunc):
self.application = application
self.authenticate = AuthBasicAuthenticator(realm, authfunc)
def __call__(self, environ, start_response):
username = REMOTE_USER(environ)
if not username:
result = self.authenticate(environ)
if isinstance(result, str):
AUTH_TYPE.update(environ, 'basic')
REMOTE_USER.update(environ, result)
else:
return result.wsgi_application(environ, start_response)
return self.application(environ, start_response)
middleware = AuthBasicHandler
__all__ = ['AuthBasicHandler']
if "__main__" == __name__:
import doctest
doctest.testmod(optionflags=doctest.ELLIPSIS)
|