def authenticate(self, request): if not 'HTTP_AUTHORIZATION' in request.META: return False if not python_digest.is_digest_credential(request.META['HTTP_AUTHORIZATION']): return False digest_response = python_digest.parse_digest_credentials( request.META['HTTP_AUTHORIZATION']) if not digest_response: _l.debug('authentication failure: supplied digest credentials could not be ' \ 'parsed: "%s".' % request.META['HTTP_AUTHORIZATION']) return False if not digest_response.realm == self.realm: _l.debug('authentication failure: supplied realm "%s" does not match ' \ 'configured realm "%s".' % ( digest_response.realm, self.realm)) return False if not python_digest.validate_nonce(digest_response.nonce, self.secret_key): _l.debug('authentication failure: nonce validation failed.') return False partial_digest = self._account_storage.get_partial_digest(digest_response.username) if not partial_digest: _l.debug('authentication failure: no partial digest available for user "%s".' \ % digest_response.username) return False calculated_request_digest = python_digest.calculate_request_digest( method=request.method, digest_response=digest_response, partial_digest=partial_digest) if not calculated_request_digest == digest_response.response: _l.debug('authentication failure: supplied request digest does not match ' \ 'calculated request digest.') return False if not python_digest.validate_uri(digest_response.uri, request.path): _l.debug('authentication failure: digest authentication uri value "%s" does not ' \ 'match value "%s" from HTTP request line.' % (digest_response.uri, request.path)) return False user = self._account_storage.get_user(digest_response.username) if not self._update_existing_nonce(user, digest_response.nonce, digest_response.nc): if (python_digest.get_nonce_timestamp(digest_response.nonce) + self.timeout < time.time()): _l.debug('authentication failure: attempt to establish a new session with ' \ 'a stale nonce.') return False if not self._store_nonce(user, digest_response.nonce, digest_response.nc): _l.debug('authentication failure: attempt to establish a previously used ' \ 'or nonce count.') return False request.user = user return True
def test_authenticate_nonce(self): testuser = User.objects.create_user(username='******', email='*****@*****.**', password='******') User.objects.create_user(username='******', email='*****@*****.**', password='******') nonce = python_digest.calculate_nonce(time.time(), secret=settings.SECRET_KEY) first_request = self.create_mock_request(username=testuser.username, password='******', nonce=nonce) first_request.user = testuser # same nonce, same nonce count, will fail second_request = self.create_mock_request(username=testuser.username, password='******', nonce=nonce) # same nonce, new nonce count, it works third_request = self.create_mock_request(username=testuser.username, password='******', nonce=nonce, nonce_count=2) third_request.user = testuser authenticator = HttpDigestAuthenticator() assert 'HTTP_AUTHORIZATION' in first_request.META assert python_digest.is_digest_credential( first_request.META['HTTP_AUTHORIZATION']) self.assertTrue( HttpDigestAuthenticator.contains_digest_credentials(first_request)) transaction.set_autocommit(False) self.assertTrue(authenticator.authenticate(first_request)) self.assertFalse(authenticator.authenticate(second_request)) transaction.rollback() self.assertTrue(authenticator.authenticate(third_request)) transaction.commit() transaction.set_autocommit(True)
def test_authenticate_nonce(self): testuser = User.objects.create_user( username='******', email='*****@*****.**', password='******') User.objects.create_user( username='******', email='*****@*****.**', password='******') nonce=python_digest.calculate_nonce(time.time(), secret=settings.SECRET_KEY) first_request = self.create_mock_request(username=testuser.username, password='******', nonce=nonce) first_request.user = testuser # same nonce, same nonce count, will fail second_request = self.create_mock_request(username=testuser.username, password='******', nonce=nonce) # same nonce, new nonce count, it works third_request = self.create_mock_request(username=testuser.username, password='******', nonce=nonce, nonce_count=2) third_request.user = testuser authenticator = HttpDigestAuthenticator() assert 'HTTP_AUTHORIZATION' in first_request.META assert python_digest.is_digest_credential(first_request.META['HTTP_AUTHORIZATION']) self.assertTrue(HttpDigestAuthenticator.contains_digest_credentials( first_request )) transaction.set_autocommit(False) self.assertTrue(authenticator.authenticate(first_request)) self.assertFalse(authenticator.authenticate(second_request)) transaction.rollback() self.assertTrue(authenticator.authenticate(third_request)) transaction.commit() transaction.set_autocommit(True)
def authenticate(self, request): if not 'HTTP_AUTHORIZATION' in request.META: return False if not python_digest.is_digest_credential(request.META['HTTP_AUTHORIZATION']): return False try: unicode(request.META['HTTP_AUTHORIZATION'], 'utf-8') except UnicodeDecodeError: return False digest_response = python_digest.parse_digest_credentials( request.META['HTTP_AUTHORIZATION']) if not digest_response: _l.debug('authentication failure: supplied digest credentials could not be ' \ 'parsed: "%s".' % request.META['HTTP_AUTHORIZATION']) return False if not digest_response.realm == self.realm: _l.debug('authentication failure: supplied realm "%s" does not match ' \ 'configured realm "%s".' % ( digest_response.realm, self.realm)) return False if not python_digest.validate_nonce(digest_response.nonce, self.secret_key): _l.debug('authentication failure: nonce validation failed.') return False partial_digest = self._account_storage.get_partial_digest(digest_response.username) if not partial_digest: _l.debug('authentication failure: no partial digest available for user "%s".' \ % digest_response.username) return False calculated_request_digest = python_digest.calculate_request_digest( method=request.method, digest_response=digest_response, partial_digest=partial_digest) if not calculated_request_digest == digest_response.response: _l.debug('authentication failure: supplied request digest does not match ' \ 'calculated request digest.') if self.failure_callback: self.failure_callback(request, digest_response.username) return False if not python_digest.validate_uri(digest_response.uri, request.path): _l.debug('authentication failure: digest authentication uri value "%s" does not ' \ 'match value "%s" from HTTP request line.' % (digest_response.uri, request.path)) return False user = self._account_storage.get_user(digest_response.username) if not self._update_existing_nonce(user, digest_response.nonce, digest_response.nc): if (python_digest.get_nonce_timestamp(digest_response.nonce) + self.timeout < time.time()): _l.debug('authentication failure: attempt to establish a new session with ' \ 'a stale nonce.') return False if not self._store_nonce(user, digest_response.nonce, digest_response.nc): _l.debug('authentication failure: attempt to establish a previously used ' \ 'or nonce count.') return False request.user = user return True
def contains_digest_credentials(request): return ('HTTP_AUTHORIZATION' in request.META and python_digest.is_digest_credential(request.META['HTTP_AUTHORIZATION']))
def authenticate(self, request): """ Base authentication method, all checks here """ if not request.headers.get('authorization'): return False if not python_digest.is_digest_credential( request.headers.get('authorization')): return False digest_response = python_digest.parse_digest_credentials( request.headers.get('authorization')) if not digest_response: log.debug('authentication failure: supplied digest credentials' ' could not be parsed: "%s".' % request.headers.get('authorization')) return False if not digest_response.username: return False if not digest_response.realm == self.realm: log.debug('authentication failure: supplied realm "%s"' 'does not match configured realm "%s".' % (digest_response.realm, self.realm)) return False if not python_digest.validate_nonce( digest_response.nonce, self.secret_key): log.debug('authentication failure: nonce validation failed.') return False partial_digest = self._account_storage.get_partial_digest( digest_response.username) if not partial_digest: log.debug('authentication failure: no partial digest available' ' for user "%s".' % digest_response.username) return False calculated_request_digest = python_digest.calculate_request_digest( method=request.method, digest_response=digest_response, partial_digest=partial_digest) if not calculated_request_digest == digest_response.response: log.debug('authentication failure: supplied request digest' 'does not match calculated request digest.') return False if not python_digest.validate_uri( digest_response.uri, urllib.parse.unquote(request.path)): log.debug('authentication failure: digest authentication uri value' '"%s" does not match value "%s" from HTTP' 'request line.' % (digest_response.uri, request.path)) return False if not self._account_storage.is_admin(digest_response.username): log.debug('authentication failure: user not in operator admin.') return False if hasattr(request,'session') and request.session.data.nonce != digest_response.nonce: if (int(python_digest.get_nonce_timestamp(digest_response.nonce)) + self.timeout < time.time()): log.debug('authentication failure: attempt to establish' ' a new session with a stale nonce.') return False if not self._store_nonce(digest_response.nonce, request): log.debug('authentication failure: attempt to establish' ' a previously used or nonce count.') return False request.user = self._account_storage.get_by_login( digest_response.username) return True
def contains_digest_credentials(request): return (request.headers.get('authorization') and python_digest.is_digest_credential( request.headers.get('authorization')))