summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Lennox <jamielennox@redhat.com>2015-10-02 07:17:21 +1000
committerJamie Lennox <jamielennox@redhat.com>2015-10-02 22:23:06 +0000
commit90c5838074fcb5d64fa3aaadf4a61eed606cd9d3 (patch)
tree9875742f4355404b7d052a4f613160d34c9f46fc
parent87e0cb92b64838664a3e7f0e5bf5a4779c90d971 (diff)
downloadpython-keystoneclient-90c5838074fcb5d64fa3aaadf4a61eed606cd9d3.tar.gz
Redirect on 303 in SAML plugin1.7.2
The SAML plugin handles redirects in a custom manner but currently only checks for the 302 redirect code. This doesn't cover the mod_auth_mellon case which responds with a 303. Also handle the 303 redirect case. Change-Id: Idab5f381fcbfb8c561184845d3aa5c8aab142ecd Closes-Bug: #1501918 (cherry picked from commit 9cd71c064c77a22a0a58084a2abab77b023017b5)
-rw-r--r--keystoneclient/contrib/auth/v3/saml2.py18
-rw-r--r--keystoneclient/tests/unit/v3/test_auth_saml2.py27
2 files changed, 36 insertions, 9 deletions
diff --git a/keystoneclient/contrib/auth/v3/saml2.py b/keystoneclient/contrib/auth/v3/saml2.py
index 929d99e..3a311d4 100644
--- a/keystoneclient/contrib/auth/v3/saml2.py
+++ b/keystoneclient/contrib/auth/v3/saml2.py
@@ -26,6 +26,8 @@ from keystoneclient.i18n import _
class _BaseSAMLPlugin(v3.AuthConstructor):
HTTP_MOVED_TEMPORARILY = 302
+ HTTP_SEE_OTHER = 303
+
PROTOCOL = 'saml2'
@staticmethod
@@ -192,9 +194,9 @@ class Saml2UnscopedToken(_BaseSAMLPlugin):
# Override to remove deprecation.
self._password = value
- def _handle_http_302_ecp_redirect(self, session, response, method,
- **kwargs):
- if response.status_code != self.HTTP_MOVED_TEMPORARILY:
+ def _handle_http_ecp_redirect(self, session, response, method, **kwargs):
+ if response.status_code not in (self.HTTP_MOVED_TEMPORARILY,
+ self.HTTP_SEE_OTHER):
return response
location = response.headers['location']
@@ -327,7 +329,7 @@ class Saml2UnscopedToken(_BaseSAMLPlugin):
managed URL, for instance: ``https://<host>:<port>/Shibboleth.sso/
SAML2/ECP``.
Upon success the there's a session created and access to the protected
- resource is granted. Many implementations of the SP return HTTP 302
+ resource is granted. Many implementations of the SP return HTTP 302/303
status code pointing to the protected URL (``https://<host>:<port>/v3/
OS-FEDERATION/identity_providers/{identity_provider}/protocols/
{protocol_id}/auth`` in this case). Saml2 plugin should point to that
@@ -344,11 +346,11 @@ class Saml2UnscopedToken(_BaseSAMLPlugin):
data=etree.tostring(self.saml2_idp_authn_response),
authenticated=False, redirect=False)
- # Don't follow HTTP specs - after the HTTP 302 response don't repeat
- # the call directed to the Location URL. In this case, this is an
- # indication that saml2 session is now active and protected resource
+ # Don't follow HTTP specs - after the HTTP 302/303 response don't
+ # repeat the call directed to the Location URL. In this case, this is
+ # an indication that saml2 session is now active and protected resource
# can be accessed.
- response = self._handle_http_302_ecp_redirect(
+ response = self._handle_http_ecp_redirect(
session, response, method='GET',
headers=self.ECP_SP_SAML2_REQUEST_HEADERS)
diff --git a/keystoneclient/tests/unit/v3/test_auth_saml2.py b/keystoneclient/tests/unit/v3/test_auth_saml2.py
index d64d962..e8eb9f1 100644
--- a/keystoneclient/tests/unit/v3/test_auth_saml2.py
+++ b/keystoneclient/tests/unit/v3/test_auth_saml2.py
@@ -283,7 +283,32 @@ class AuthenticateviaSAML2Tests(utils.TestCase):
self.assertEqual(self.FEDERATION_AUTH_URL,
response.headers['location'])
- response = self.saml2plugin._handle_http_302_ecp_redirect(
+ response = self.saml2plugin._handle_http_ecp_redirect(
+ self.session, response, 'GET')
+
+ self.assertEqual(self.FEDERATION_AUTH_URL, response.request.url)
+ self.assertEqual('GET', response.request.method)
+
+ def test_custom_303_redirection(self):
+ self.requests_mock.post(
+ self.SHIB_CONSUMER_URL,
+ text='BODY',
+ headers={'location': self.FEDERATION_AUTH_URL},
+ status_code=303)
+
+ self.requests_mock.get(
+ self.FEDERATION_AUTH_URL,
+ json=saml2_fixtures.UNSCOPED_TOKEN,
+ headers={'X-Subject-Token': saml2_fixtures.UNSCOPED_TOKEN_HEADER})
+
+ self.session.redirect = False
+ response = self.session.post(
+ self.SHIB_CONSUMER_URL, data='CLIENT BODY')
+ self.assertEqual(303, response.status_code)
+ self.assertEqual(self.FEDERATION_AUTH_URL,
+ response.headers['location'])
+
+ response = self.saml2plugin._handle_http_ecp_redirect(
self.session, response, 'GET')
self.assertEqual(self.FEDERATION_AUTH_URL, response.request.url)