From 4c66b13f9c53382502d8fe394191657eaee29e5c Mon Sep 17 00:00:00 2001 From: nitzmahone Date: Mon, 16 May 2016 14:24:43 -0700 Subject: [PATCH] make mutual auth error sanitization optional added test coverage, doc update --- README.rst | 21 ++++++++++++++++++--- requests_kerberos/kerberos_.py | 6 ++++-- test_requests_kerberos.py | 9 +++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 09b0bf0..70e60eb 100644 --- a/README.rst +++ b/README.rst @@ -24,11 +24,26 @@ the 401 response. Mutual Authentication --------------------- +REQUIRED +^^^^^^^^ + By default, ``HTTPKerberosAuth`` will require mutual authentication from the server, and if a server emits a non-error response which cannot be -authenticated, a ``requests_kerberos.errors.MutualAuthenticationError`` will be -raised. If a server emits an error which cannot be authenticated, it will be -returned to the user but with its contents and headers stripped. +authenticated, a ``requests_kerberos.errors.MutualAuthenticationError`` will +be raised. If a server emits an error which cannot be authenticated, it will +be returned to the user but with its contents and headers stripped. If the +response content is more important than the need for mutual auth on errors, +(eg, for certain WinRM calls) the stripping behavior can be suppressed by +setting ``sanitize_mutual_error_response=False``: + +.. code-block:: pycon + + >>> import requests + >>> from requests_kerberos import HTTPKerberosAuth, REQUIRED + >>> kerberos_auth = HTTPKerberosAuth(mutual_authentication=REQUIRED, sanitize_mutual_error_response=False) + >>> r = requests.get("https://windows.example.org/wsman", auth=kerberos_auth) + ... + OPTIONAL ^^^^^^^^ diff --git a/requests_kerberos/kerberos_.py b/requests_kerberos/kerberos_.py index 4656d9d..633217a 100644 --- a/requests_kerberos/kerberos_.py +++ b/requests_kerberos/kerberos_.py @@ -85,7 +85,7 @@ class HTTPKerberosAuth(AuthBase): def __init__( self, mutual_authentication=REQUIRED, service="HTTP", delegate=False, force_preemptive=False, - principal=None, hostname_override=None): + principal=None, hostname_override=None, sanitize_mutual_error_response=True): self.context = {} self.mutual_authentication = mutual_authentication self.delegate = delegate @@ -94,6 +94,7 @@ class HTTPKerberosAuth(AuthBase): self.force_preemptive = force_preemptive self.principal = principal self.hostname_override = hostname_override + self.sanitize_mutual_error_response = sanitize_mutual_error_response def generate_request_header(self, response, host, is_preemptive=False): """ @@ -224,7 +225,8 @@ class HTTPKerberosAuth(AuthBase): log.error("handle_other(): Mutual authentication unavailable " "on {0} response".format(response.status_code)) - if self.mutual_authentication == REQUIRED: + if self.mutual_authentication == REQUIRED and \ + self.sanitize_mutual_error_response: return SanitizedResponse(response) else: return response diff --git a/test_requests_kerberos.py b/test_requests_kerberos.py index 45af2b1..a8c3350 100644 --- a/test_requests_kerberos.py +++ b/test_requests_kerberos.py @@ -403,6 +403,7 @@ class KerberosTestCase(unittest.TestCase): r = auth.handle_response(response_500) + self.assertIsInstance(r, requests_kerberos.kerberos_.SanitizedResponse) self.assertNotEqual(r, response_500) self.assertNotEqual(r.headers, response_500.headers) self.assertEqual(r.status_code, response_500.status_code) @@ -416,6 +417,14 @@ class KerberosTestCase(unittest.TestCase): self.assertFalse(clientStep_error.called) + # re-test with error response sanitizing disabled + auth = requests_kerberos.HTTPKerberosAuth(sanitize_mutual_error_response=False) + auth.context = {"www.example.org": "CTX"} + + r = auth.handle_response(response_500) + + self.assertNotIsInstance(r, requests_kerberos.kerberos_.SanitizedResponse) + def test_handle_response_500_mutual_auth_optional_failure(self): with patch(kerberos_module_name+'.authGSSClientStep', clientStep_error):