Fix closes Issue #11799: urllib.request Authentication Handlers will raise a

ValueError when presented with an unsupported Authentication Scheme.
This commit is contained in:
Senthil Kumaran 2011-05-11 21:17:57 +08:00
parent cc99528d87
commit 4de00a2e87
4 changed files with 63 additions and 16 deletions

View File

@ -240,10 +240,11 @@ The following classes are provided:
.. class:: HTTPBasicAuthHandler(password_mgr=None)
Handle authentication with the remote host. *password_mgr*, if given, should be
something that is compatible with :class:`HTTPPasswordMgr`; refer to section
:ref:`http-password-mgr` for information on the interface that must be
supported.
Handle authentication with the remote host. *password_mgr*, if given, should
be something that is compatible with :class:`HTTPPasswordMgr`; refer to
section :ref:`http-password-mgr` for information on the interface that must
be supported. HTTPBasicAuthHandler will raise a :exc:`ValueError` when
presented with a wrong Authentication scheme.
.. class:: ProxyBasicAuthHandler(password_mgr=None)
@ -265,10 +266,19 @@ The following classes are provided:
.. class:: HTTPDigestAuthHandler(password_mgr=None)
Handle authentication with the remote host. *password_mgr*, if given, should be
something that is compatible with :class:`HTTPPasswordMgr`; refer to section
:ref:`http-password-mgr` for information on the interface that must be
supported.
Handle authentication with the remote host. *password_mgr*, if given, should
be something that is compatible with :class:`HTTPPasswordMgr`; refer to
section :ref:`http-password-mgr` for information on the interface that must
be supported. When both Digest Authentication Handler and Basic
Authentication Handler are both added, Digest Authentication is always tried
first. If the Digest Authentication returns a 40x response again, it is sent
to Basic Authentication handler to Handle. This Handler method will raise a
:exc:`ValueError` when presented with an authentication scheme other than
Digest or Basic.
..versionchanged:: 3.3
Raise ValueError on unsupported Authentication Scheme.
.. class:: ProxyDigestAuthHandler(password_mgr=None)

View File

@ -5,6 +5,7 @@ import os
import io
import socket
import array
import sys
import urllib.request
# The proxy bypass method imported below has logic specific to the OSX
@ -1162,6 +1163,8 @@ class HandlerTests(unittest.TestCase):
self.assertEqual(req.get_host(), "proxy.example.com:3128")
self.assertEqual(req.get_header("Proxy-authorization"),"FooBar")
# TODO: This should be only for OSX
@unittest.skipUnless(sys.platform == 'darwin', "only relevant for OSX")
def test_osx_proxy_bypass(self):
bypass = {
'exclude_simple': False,
@ -1265,6 +1268,26 @@ class HandlerTests(unittest.TestCase):
# _test_basic_auth called .open() twice)
self.assertEqual(opener.recorded, ["digest", "basic"]*2)
def test_unsupported_auth_digest_handler(self):
opener = OpenerDirector()
# While using DigestAuthHandler
digest_auth_handler = urllib.request.HTTPDigestAuthHandler(None)
http_handler = MockHTTPHandler(
401, 'WWW-Authenticate: Kerberos\r\n\r\n')
opener.add_handler(digest_auth_handler)
opener.add_handler(http_handler)
self.assertRaises(ValueError,opener.open,"http://www.example.com")
def test_unsupported_auth_basic_handler(self):
# While using BasicAuthHandler
opener = OpenerDirector()
basic_auth_handler = urllib.request.HTTPBasicAuthHandler(None)
http_handler = MockHTTPHandler(
401, 'WWW-Authenticate: NTLM\r\n\r\n')
opener.add_handler(basic_auth_handler)
opener.add_handler(http_handler)
self.assertRaises(ValueError,opener.open,"http://www.example.com")
def _test_basic_auth(self, opener, auth_handler, auth_header,
realm, http_handler, password_manager,
request_url, protected_url):
@ -1302,6 +1325,7 @@ class HandlerTests(unittest.TestCase):
self.assertEqual(len(http_handler.requests), 1)
self.assertFalse(http_handler.requests[0].has_header(auth_header))
class MiscTests(unittest.TestCase):
def test_build_opener(self):

View File

@ -825,14 +825,20 @@ class AbstractBasicAuthHandler:
self.retried += 1
if authreq:
mo = AbstractBasicAuthHandler.rx.search(authreq)
if mo:
scheme, quote, realm = mo.groups()
if scheme.lower() == 'basic':
response = self.retry_http_basic_auth(host, req, realm)
if response and response.code != 401:
self.retried = 0
return response
scheme = authreq.split()[0]
if not scheme.lower() == 'basic':
raise ValueError("AbstractBasicAuthHandler does not"
" support the following scheme: '%s'" %
scheme)
else:
mo = AbstractBasicAuthHandler.rx.search(authreq)
if mo:
scheme, quote, realm = mo.groups()
if scheme.lower() == 'basic':
response = self.retry_http_basic_auth(host, req, realm)
if response and response.code != 401:
self.retried = 0
return response
def retry_http_basic_auth(self, host, req, realm):
user, pw = self.passwd.find_user_password(realm, host)
@ -918,6 +924,9 @@ class AbstractDigestAuthHandler:
scheme = authreq.split()[0]
if scheme.lower() == 'digest':
return self.retry_http_digest_auth(req, authreq)
elif not scheme.lower() == 'basic':
raise ValueError("AbstractDigestAuthHandler does not support"
" the following scheme: '%s'" % scheme)
def retry_http_digest_auth(self, req, auth):
token, challenge = auth.split(' ', 1)

View File

@ -143,6 +143,10 @@ Core and Builtins
Library
-------
- Issue #11799: urllib.request Authentication Handlers will raise a ValueError
when presented with an unsupported Authentication Scheme. Patch contributed
by Yuval Greenfield.
- Issue #10419, #6011: build_scripts command of distutils handles correctly
non-ASCII path (path to the Python executable). Open and write the script in
binary mode, but ensure that the shebang is decodable from UTF-8 and from the