fix(HTTPUnauthorized): Add support for setting the realm to the HTTPUnauthorized class
Based on RFC 7235, add challenges to HTTP Unauthorized to indicate authentication scheme. A server generating a 401 must send a WWW-Authenticate header field containing at least one challenge BREAKING CHANGE: Add new parameter to the __init__ method of class HTTPUnauthorized to add determine authentication scheme in the WWW-Authenticate header field when a 401 (Unauthorized) is generated Fixes #430 Fix pep8 error Fix docstring
This commit is contained in:
@@ -49,18 +49,18 @@ class HTTPUnauthorized(HTTPError):
|
||||
title (str): Error title (e.g., 'Authentication Required').
|
||||
description (str): Human-friendly description of the error, along with
|
||||
a helpful suggestion or two.
|
||||
scheme (str): Authentication scheme to use as the value of the
|
||||
WWW-Authenticate header in the response (default ``None``).
|
||||
challenges (iterable of str): One or more authentication
|
||||
challenges to use as the value of the WWW-Authenticate header in
|
||||
the response.
|
||||
kwargs (optional): Same as for ``HTTPError``.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, title, description, **kwargs):
|
||||
def __init__(self, title, description, challenges, **kwargs):
|
||||
headers = kwargs.setdefault('headers', {})
|
||||
|
||||
scheme = kwargs.pop('scheme', None)
|
||||
if scheme is not None:
|
||||
headers['WWW-Authenticate'] = scheme
|
||||
if challenges:
|
||||
headers['WWW-Authenticate'] = ', '.join(challenges)
|
||||
|
||||
HTTPError.__init__(self, status.HTTP_401, title, description, **kwargs)
|
||||
|
||||
|
||||
@@ -74,14 +74,17 @@ class UnauthorizedResource:
|
||||
def on_get(self, req, resp):
|
||||
raise falcon.HTTPUnauthorized('Authentication Required',
|
||||
'Missing or invalid token header.',
|
||||
scheme='Token; UUID')
|
||||
['Basic realm="simple"'])
|
||||
|
||||
|
||||
class UnauthorizedResourceSchemaless:
|
||||
|
||||
def on_get(self, req, resp):
|
||||
def on_post(self, req, resp):
|
||||
raise falcon.HTTPUnauthorized('Authentication Required',
|
||||
'Missing or invalid token header.')
|
||||
'Missing or invalid token header.',
|
||||
['Newauth realm="apps"',
|
||||
'Basic realm="simple"'])
|
||||
|
||||
def on_put(self, req, resp):
|
||||
raise falcon.HTTPUnauthorized('Authentication Required',
|
||||
'Missing or invalid token header.', [])
|
||||
|
||||
|
||||
class NotFoundResource:
|
||||
@@ -454,15 +457,20 @@ class TestHTTPError(testing.TestBase):
|
||||
self.simulate_request('/401')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_401)
|
||||
self.assertIn(('www-authenticate', 'Token; UUID'),
|
||||
self.assertIn(('www-authenticate', 'Basic realm="simple"'),
|
||||
self.srmock.headers)
|
||||
|
||||
def test_401_schemaless(self):
|
||||
self.api.add_route('/401', UnauthorizedResourceSchemaless())
|
||||
self.simulate_request('/401')
|
||||
self.simulate_request('/401', method='POST')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_401)
|
||||
self.assertNotIn(('www-authenticate', 'Token'), self.srmock.headers)
|
||||
self.assertIn(('www-authenticate', 'Newauth realm="apps", '
|
||||
'Basic realm="simple"'),
|
||||
self.srmock.headers)
|
||||
|
||||
self.simulate_request('/401', method='PUT')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_401)
|
||||
self.assertNotIn(('www-authenticate', []), self.srmock.headers)
|
||||
|
||||
def test_404_without_body(self):
|
||||
self.api.add_route('/404', NotFoundResource())
|
||||
|
||||
Reference in New Issue
Block a user