OLD | NEW |
(Empty) | |
| 1 # This file is part of CherryPy <http://www.cherrypy.org/> |
| 2 # -*- coding: utf-8 -*- |
| 3 # vim:ts=4:sw=4:expandtab:fileencoding=utf-8 |
| 4 |
| 5 __doc__ = """This module provides a CherryPy 3.x tool which implements |
| 6 the server-side of HTTP Basic Access Authentication, as described in :rfc:`2617`
. |
| 7 |
| 8 Example usage, using the built-in checkpassword_dict function which uses a dict |
| 9 as the credentials store:: |
| 10 |
| 11 userpassdict = {'bird' : 'bebop', 'ornette' : 'wayout'} |
| 12 checkpassword = cherrypy.lib.auth_basic.checkpassword_dict(userpassdict) |
| 13 basic_auth = {'tools.auth_basic.on': True, |
| 14 'tools.auth_basic.realm': 'earth', |
| 15 'tools.auth_basic.checkpassword': checkpassword, |
| 16 } |
| 17 app_config = { '/' : basic_auth } |
| 18 |
| 19 """ |
| 20 |
| 21 __author__ = 'visteya' |
| 22 __date__ = 'April 2009' |
| 23 |
| 24 import binascii |
| 25 from cherrypy._cpcompat import base64_decode |
| 26 import cherrypy |
| 27 |
| 28 |
| 29 def checkpassword_dict(user_password_dict): |
| 30 """Returns a checkpassword function which checks credentials |
| 31 against a dictionary of the form: {username : password}. |
| 32 |
| 33 If you want a simple dictionary-based authentication scheme, use |
| 34 checkpassword_dict(my_credentials_dict) as the value for the |
| 35 checkpassword argument to basic_auth(). |
| 36 """ |
| 37 def checkpassword(realm, user, password): |
| 38 p = user_password_dict.get(user) |
| 39 return p and p == password or False |
| 40 |
| 41 return checkpassword |
| 42 |
| 43 |
| 44 def basic_auth(realm, checkpassword, debug=False): |
| 45 """A CherryPy tool which hooks at before_handler to perform |
| 46 HTTP Basic Access Authentication, as specified in :rfc:`2617`. |
| 47 |
| 48 If the request has an 'authorization' header with a 'Basic' scheme, this |
| 49 tool attempts to authenticate the credentials supplied in that header. If |
| 50 the request has no 'authorization' header, or if it does but the scheme is |
| 51 not 'Basic', or if authentication fails, the tool sends a 401 response with |
| 52 a 'WWW-Authenticate' Basic header. |
| 53 |
| 54 realm |
| 55 A string containing the authentication realm. |
| 56 |
| 57 checkpassword |
| 58 A callable which checks the authentication credentials. |
| 59 Its signature is checkpassword(realm, username, password). where |
| 60 username and password are the values obtained from the request's |
| 61 'authorization' header. If authentication succeeds, checkpassword |
| 62 returns True, else it returns False. |
| 63 |
| 64 """ |
| 65 |
| 66 if '"' in realm: |
| 67 raise ValueError('Realm cannot contain the " (quote) character.') |
| 68 request = cherrypy.serving.request |
| 69 |
| 70 auth_header = request.headers.get('authorization') |
| 71 if auth_header is not None: |
| 72 try: |
| 73 scheme, params = auth_header.split(' ', 1) |
| 74 if scheme.lower() == 'basic': |
| 75 username, password = base64_decode(params).split(':', 1) |
| 76 if checkpassword(realm, username, password): |
| 77 if debug: |
| 78 cherrypy.log('Auth succeeded', 'TOOLS.AUTH_BASIC') |
| 79 request.login = username |
| 80 return # successful authentication |
| 81 except (ValueError, binascii.Error): # split() error, base64.decodestrin
g() error |
| 82 raise cherrypy.HTTPError(400, 'Bad Request') |
| 83 |
| 84 # Respond with 401 status and a WWW-Authenticate header |
| 85 cherrypy.serving.response.headers['www-authenticate'] = 'Basic realm="%s"' %
realm |
| 86 raise cherrypy.HTTPError(401, "You are not authorized to access that resourc
e") |
| 87 |
OLD | NEW |