summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDariusz Górecki <darek.krk@gmail.com>2016-07-01 09:42:30 +0100
committerDariusz Górecki <darek.krk@gmail.com>2016-07-01 09:47:12 +0100
commitc895f874184371ff5798748b1c7234128ca4b25e (patch)
tree8bca62bf747fe3ffb1b7bbbe50bf92a8e70f2721
parentd901849a1db80eaa293e908fcff2d2a010fa567f (diff)
downloadpyramid-c895f874184371ff5798748b1c7234128ca4b25e.tar.gz
pyramid-c895f874184371ff5798748b1c7234128ca4b25e.tar.bz2
pyramid-c895f874184371ff5798748b1c7234128ca4b25e.zip
ref #2659 public HTTP Basic credentials extraction
-rw-r--r--pyramid/authentication.py77
1 files changed, 46 insertions, 31 deletions
diff --git a/pyramid/authentication.py b/pyramid/authentication.py
index 9bf1de62e..95d6a710d 100644
--- a/pyramid/authentication.py
+++ b/pyramid/authentication.py
@@ -1128,7 +1128,7 @@ class BasicAuthAuthenticationPolicy(CallbackAuthenticationPolicy):
def unauthenticated_userid(self, request):
""" The userid parsed from the ``Authorization`` request header."""
- credentials = self._get_credentials(request)
+ credentials = extract_http_basic_credentials(request)
if credentials:
return credentials[0]
@@ -1145,42 +1145,14 @@ class BasicAuthAuthenticationPolicy(CallbackAuthenticationPolicy):
return [('WWW-Authenticate', 'Basic realm="%s"' % self.realm)]
def callback(self, username, request):
- # Username arg is ignored. Unfortunately _get_credentials winds up
+ # Username arg is ignored. Unfortunately extract_http_basic_credentials winds up
# getting called twice when authenticated_userid is called. Avoiding
# that, however, winds up duplicating logic from the superclass.
- credentials = self._get_credentials(request)
+ credentials = extract_http_basic_credentials(request)
if credentials:
username, password = credentials
return self.check(username, password, request)
- def _get_credentials(self, request):
- authorization = request.headers.get('Authorization')
- if not authorization:
- return None
- try:
- authmeth, auth = authorization.split(' ', 1)
- except ValueError: # not enough values to unpack
- return None
- if authmeth.lower() != 'basic':
- return None
-
- try:
- authbytes = b64decode(auth.strip())
- except (TypeError, binascii.Error): # can't decode
- return None
-
- # try utf-8 first, then latin-1; see discussion in
- # https://github.com/Pylons/pyramid/issues/898
- try:
- auth = authbytes.decode('utf-8')
- except UnicodeDecodeError:
- auth = authbytes.decode('latin-1')
-
- try:
- username, password = auth.split(':', 1)
- except ValueError: # not enough values to unpack
- return None
- return username, password
class _SimpleSerializer(object):
def loads(self, bstruct):
@@ -1188,3 +1160,46 @@ class _SimpleSerializer(object):
def dumps(self, appstruct):
return bytes_(appstruct)
+
+
+def extract_http_basic_credentials(request):
+ """ A helper function for extraction of HTTP Basic credentials
+ from a given `request`.
+
+ ``request``
+ The request object
+ """
+ try:
+ # First try authorization extraction logic from WebOb
+ try:
+ authmeth, auth = request.authorization
+ except AttributeError: # Probably a DummyRequest
+ authorization = request.headers.get('Authorization')
+ if not authorization:
+ return None
+
+ authmeth, auth = authorization.split(' ', 1)
+ except (ValueError, TypeError):
+ # not enough values to unpack or None is not iterable
+ return None
+
+ if authmeth.lower() != 'basic':
+ return None
+
+ try:
+ authbytes = b64decode(auth.strip())
+ except (TypeError, binascii.Error): # can't decode
+ return None
+
+ # try utf-8 first, then latin-1; see discussion in
+ # https://github.com/Pylons/pyramid/issues/898
+ try:
+ auth = authbytes.decode('utf-8')
+ except UnicodeDecodeError:
+ auth = authbytes.decode('latin-1')
+
+ try:
+ username, password = auth.split(':', 1)
+ except ValueError: # not enough values to unpack
+ return None
+ return username, password