summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-02-09 23:31:00 +0000
committerGerrit Code Review <review@openstack.org>2015-02-09 23:31:00 +0000
commit2b98d531841da649ffc8dbf79495cf6942f98cad (patch)
treec7c41c5674a481c3235773bb1a49932fac87cf5a
parentbf700779e12b5e6e47fd8e96362625bf909115e5 (diff)
parent136f85c01ad4da01f9e073619f22eed5ca2378cc (diff)
downloadkeystonemiddleware-2b98d531841da649ffc8dbf79495cf6942f98cad.tar.gz
Merge "fallback to online validation if offline validation fails"
-rw-r--r--keystonemiddleware/auth_token.py37
-rw-r--r--keystonemiddleware/tests/test_auth_token_middleware.py29
2 files changed, 52 insertions, 14 deletions
diff --git a/keystonemiddleware/auth_token.py b/keystonemiddleware/auth_token.py
index 7aa7d6b..33476eb 100644
--- a/keystonemiddleware/auth_token.py
+++ b/keystonemiddleware/auth_token.py
@@ -498,6 +498,10 @@ class ConfigurationError(Exception):
pass
+class RevocationListError(Exception):
+ pass
+
+
class _MiniResp(object):
def __init__(self, error_message, env, headers=[]):
# The HEAD method is unique: it must never return a body, even if
@@ -940,19 +944,26 @@ class AuthProtocol(object):
_('Token authorization failed'))
self._confirm_token_bind(data, env)
else:
+ verified = None
# Token wasn't cached. In this case, the token needs to be
# checked that it's not expired, and also put in the cache.
- if cms.is_pkiz(token):
- verified = self._verify_pkiz_token(token, token_ids)
- data = jsonutils.loads(verified)
- expires = _confirm_token_not_expired(data)
- elif cms.is_asn1_token(token):
- verified = self._verify_signed_token(token, token_ids)
+ try:
+ if cms.is_pkiz(token):
+ verified = self._verify_pkiz_token(token, token_ids)
+ elif cms.is_asn1_token(token):
+ verified = self._verify_signed_token(token, token_ids)
+ except exceptions.CertificateConfigError:
+ self._LOG.warn(_LW('Fetch certificate config failed, '
+ 'fallback to online validation.'))
+ except RevocationListError:
+ self._LOG.warn(_LW('Fetch revocation list failed, '
+ 'fallback to online validation.'))
+
+ if verified is not None:
data = jsonutils.loads(verified)
expires = _confirm_token_not_expired(data)
else:
- data = self._identity_server.verify_token(token,
- retry)
+ data = self._identity_server.verify_token(token, retry)
# No need to confirm token expiration here since
# verify_token fails for expired tokens.
expires = _get_token_expiration(data)
@@ -1563,12 +1574,14 @@ class _IdentityServer(object):
authenticated=True,
endpoint_filter={'version': (2, 0)})
except exceptions.HTTPError as e:
- raise ServiceError(_('Failed to fetch token revocation list: %d') %
- e.http_status)
+ raise RevocationListError(_('Failed to fetch token revocation '
+ 'list: %d') % e.http_status)
if response.status_code != 200:
- raise ServiceError(_('Unable to fetch token revocation list.'))
+ raise RevocationListError(_('Unable to fetch token revocation '
+ 'list.'))
if 'signed' not in data:
- raise ServiceError(_('Revocation list improperly formatted.'))
+ raise RevocationListError(_('Revocation list improperly '
+ 'formatted.'))
return data['signed']
def fetch_signing_cert(self):
diff --git a/keystonemiddleware/tests/test_auth_token_middleware.py b/keystonemiddleware/tests/test_auth_token_middleware.py
index a5bfbc4..b9bff1c 100644
--- a/keystonemiddleware/tests/test_auth_token_middleware.py
+++ b/keystonemiddleware/tests/test_auth_token_middleware.py
@@ -961,10 +961,10 @@ class CommonAuthTokenMiddlewareTest(object):
self.assertEqual(self.middleware._token_revocation_list,
in_memory_list)
- def test_invalid_revocation_list_raises_service_error(self):
+ def test_invalid_revocation_list_raises_error(self):
self.requests.get('%s/v2.0/tokens/revoked' % BASE_URI, json={})
- self.assertRaises(auth_token.ServiceError,
+ self.assertRaises(auth_token.RevocationListError,
self.middleware._fetch_revocation_list)
def test_fetch_revocation_list(self):
@@ -1817,6 +1817,31 @@ class v3AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
self.assertIn('publicURL', endpoint)
self.assertIn('adminURL', endpoint)
+ def test_fallback_to_online_validation_with_signing_error(self):
+ self.requests.register_uri(
+ 'GET',
+ '%s/v3/OS-SIMPLE-CERT/certificates' % BASE_URI,
+ status_code=404)
+ self.assert_valid_request_200(self.token_dict['signed_token_scoped'])
+ self.assert_valid_request_200(
+ self.token_dict['signed_token_scoped_pkiz'])
+
+ def test_fallback_to_online_validation_with_ca_error(self):
+ self.requests.register_uri('GET',
+ '%s/v3/OS-SIMPLE-CERT/ca' % BASE_URI,
+ status_code=404)
+ self.assert_valid_request_200(self.token_dict['signed_token_scoped'])
+ self.assert_valid_request_200(
+ self.token_dict['signed_token_scoped_pkiz'])
+
+ def test_fallback_to_online_validation_with_revocation_list_error(self):
+ self.requests.register_uri('GET',
+ '%s/v2.0/tokens/revoked' % BASE_URI,
+ status_code=404)
+ self.assert_valid_request_200(self.token_dict['signed_token_scoped'])
+ self.assert_valid_request_200(
+ self.token_dict['signed_token_scoped_pkiz'])
+
class TokenEncodingTest(testtools.TestCase):
def test_unquoted_token(self):