| 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 | from tornado.web import RequestHandler from tornado.escape import utf8 from hashlib import md5 class BasicAuthHandler(RequestHandler):     def get(self):         realm = 'renjie'         username = 'foo'         password = 'bar'         # Authorization: Basic base64("user:passwd")         auth_header = self.request.headers.get('Authorization', None)         if auth_header is not None:             # Basic Zm9vOmJhcg==             auth_mode, auth_base64 = auth_header.split(' ', 1)             assert auth_mode == 'Basic'             # 'Zm9vOmJhcg==' == base64("foo:bar")             auth_username, auth_password = auth_base64.decode('base64').split(':', 1)             if auth_username == username or auth_password == password:                 self.write('ok')             else:                 self.write('fail')         else:             '''             HTTP/1.1 401 Unauthorized             WWW-Authenticate: Basic realm="renjie"             '''             self.set_status(401)             self.set_header('WWW-Authenticate', 'Basic realm="%s"' % realm) class DigestAuthHandler(RequestHandler):     def get(self):         realm = 'test'         opaque = 'asdf'         # Real implementations would use a random nonce.         nonce = "1234"         username = 'foo'         password = 'bar'         '''         Authorization: Digest username="foo",                                realm="test",                                nonce="1234",                                uri="/auth/digest",                                response="e839337ef079c93238a4bf4f1ae712b3",                                opaque="asdf"         '''         auth_header = self.request.headers.get('Authorization', None)         if auth_header is not None:             auth_mode, params = auth_header.split(' ', 1)             assert auth_mode == 'Digest'             param_dict = {}             for pair in params.split(','):                 k, v = pair.strip().split('=', 1)                 if v[0] == '"' and v[-1] == '"':                     v = v[1:-1]                 param_dict[k] = v             assert param_dict['realm'] == realm             assert param_dict['opaque'] == opaque             assert param_dict['nonce'] == nonce             assert param_dict['username'] == username             assert param_dict['uri'] == self.request.path             h1 = md5(utf8('%s:%s:%s' % (username, realm, password))).hexdigest()             h2 = md5(utf8('%s:%s' % (self.request.method,                                      self.request.path))).hexdigest()             digest = md5(utf8('%s:%s:%s' % (h1, nonce, h2))).hexdigest()             if digest == param_dict['response']:                 self.write('ok')             else:                 self.write('fail')         else:             self.set_status(401)             # WWW-Authenticate: Digest realm="test", nonce="1234", opaque="asdf"             self.set_header('WWW-Authenticate',                             'Digest realm="%s", nonce="%s", opaque="%s"' %                             (realm, nonce, opaque)) |