diff options
author | asteroide <thomas.duval@orange.com> | 2016-03-04 15:50:10 +0100 |
---|---|---|
committer | asteroide <thomas.duval@orange.com> | 2016-03-04 15:50:10 +0100 |
commit | 65ab65faac57b156c4d238afa8de422f52a5a68a (patch) | |
tree | 34bc68621f261c9cba4153d5ef9a2ff2ef6449a4 /keystonemiddleware-moon/keystonemiddleware/auth_token | |
parent | 7be2f3dfff8541051c641e5715d6d70705cab5f7 (diff) |
Update KeystoneMiddleware to the stable/liberty version.
Change-Id: I225ed685dad129dc7c1d5d6a00e54c0facde0c07
Diffstat (limited to 'keystonemiddleware-moon/keystonemiddleware/auth_token')
3 files changed, 62 insertions, 21 deletions
diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py index 8987e0ea..be268da3 100644 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py +++ b/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py @@ -206,6 +206,7 @@ object is stored. """ +import binascii import datetime import logging @@ -511,7 +512,7 @@ class _BaseAuthProtocol(object): :raises exc.InvalidToken: if token is rejected """ - # 0 seconds of validity means it is invalid right now + # 0 seconds of validity means is it valid right now. if auth_ref.will_expire_soon(stale_duration=0): raise exc.InvalidToken(_('Token authorization failed')) @@ -838,8 +839,9 @@ class AuthProtocol(_BaseAuthProtocol): data = cached if self._check_revocations_for_cached: - # A token might have been revoked, regardless of initial - # mechanism used to validate it, and needs to be checked. + # A token stored in Memcached might have been revoked + # regardless of initial mechanism used to validate it, + # and needs to be checked. self._revocations.check(token_hashes) else: data = self._validate_offline(token, token_hashes) @@ -848,19 +850,19 @@ class AuthProtocol(_BaseAuthProtocol): self._token_cache.store(token_hashes[0], data) - except (exceptions.ConnectionRefused, exceptions.RequestTimeout): - self.log.debug('Token validation failure.', exc_info=True) - self.log.warning(_LW('Authorization failed for token')) - raise exc.InvalidToken(_('Token authorization failed')) - except exc.ServiceError as e: - self.log.critical(_LC('Unable to obtain admin token: %s'), e) + except (exceptions.ConnectionRefused, exceptions.RequestTimeout, + exc.RevocationListError, exc.ServiceError) as e: + self.log.critical(_LC('Unable to validate token: %s'), e) raise webob.exc.HTTPServiceUnavailable() - except Exception: + except exc.InvalidToken: self.log.debug('Token validation failure.', exc_info=True) if token_hashes: self._token_cache.store_invalid(token_hashes[0]) self.log.warning(_LW('Authorization failed for token')) - raise exc.InvalidToken(_('Token authorization failed')) + raise + except Exception: + self.log.critical(_LC('Unable to validate token'), exc_info=True) + raise webob.exc.HTTPInternalServerError() return data @@ -881,6 +883,18 @@ class AuthProtocol(_BaseAuthProtocol): 'fallback to online validation.')) else: data = jsonutils.loads(verified) + + audit_ids = None + if 'access' in data: + # It's a v2 token. + audit_ids = data['access']['token'].get('audit_ids') + else: + # It's a v3 token + audit_ids = data['token'].get('audit_ids') + + if audit_ids: + self._revocations.check_by_audit_id(audit_ids) + return data def _validate_token(self, auth_ref): @@ -905,9 +919,10 @@ class AuthProtocol(_BaseAuthProtocol): return cms.cms_verify(data, signing_cert_path, signing_ca_path, inform=inform).decode('utf-8') - except cms.subprocess.CalledProcessError as err: + except (exceptions.CMSError, + cms.subprocess.CalledProcessError) as err: self.log.warning(_LW('Verify error: %s'), err) - raise + raise exc.InvalidToken(_('Token authorization failed')) try: return verify() @@ -939,7 +954,8 @@ class AuthProtocol(_BaseAuthProtocol): verified = self._cms_verify(uncompressed, inform=cms.PKIZ_CMS_FORM) return verified # TypeError If the signed_text is not zlib compressed - except TypeError: + # binascii.Error if signed_text has incorrect base64 padding (py34) + except (TypeError, binascii.Error): raise exc.InvalidToken(signed_text) def _fetch_signing_cert(self): diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py index 98be3b2e..6fbeac27 100644 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py +++ b/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py @@ -212,25 +212,28 @@ class IdentityServer(object): try: auth_ref = self._request_strategy.verify_token(user_token) except exceptions.NotFound as e: - self._LOG.warn(_LW('Authorization failed for token')) - self._LOG.warn(_LW('Identity response: %s'), e.response.text) + self._LOG.warning(_LW('Authorization failed for token')) + self._LOG.warning(_LW('Identity response: %s'), e.response.text) + raise exc.InvalidToken(_('Token authorization failed')) except exceptions.Unauthorized as e: self._LOG.info(_LI('Identity server rejected authorization')) - self._LOG.warn(_LW('Identity response: %s'), e.response.text) + self._LOG.warning(_LW('Identity response: %s'), e.response.text) if retry: self._LOG.info(_LI('Retrying validation')) return self.verify_token(user_token, False) + msg = _('Identity server rejected authorization necessary to ' + 'fetch token data') + raise exc.ServiceError(msg) except exceptions.HttpError as e: self._LOG.error( _LE('Bad response code while validating token: %s'), e.http_status) - self._LOG.warn(_LW('Identity response: %s'), e.response.text) + self._LOG.warning(_LW('Identity response: %s'), e.response.text) + msg = _('Failed to fetch token data from identity server') + raise exc.ServiceError(msg) else: return auth_ref - msg = _('Failed to fetch token data from identity server') - raise exc.InvalidToken(msg) - def fetch_revocation_list(self): try: data = self._request_strategy.fetch_revocation_list() diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py index 8cc449ad..a68356a8 100644 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py +++ b/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py @@ -104,3 +104,25 @@ class Revocations(object): if self._any_revoked(token_ids): self._log.debug('Token is marked as having been revoked') raise exc.InvalidToken(_('Token has been revoked')) + + def check_by_audit_id(self, audit_ids): + """Check whether the audit_id appears in the revocation list. + + :raises keystonemiddleware.auth_token._exceptions.InvalidToken: + if the audit ID(s) appear in the revocation list. + + """ + revoked_tokens = self._list.get('revoked', None) + if not revoked_tokens: + # There's no revoked tokens, so nothing to do. + return + + # The audit_id may not be present in the revocation events because + # earlier versions of the identity server didn't provide them. + revoked_ids = set( + x['audit_id'] for x in revoked_tokens if 'audit_id' in x) + for audit_id in audit_ids: + if audit_id in revoked_ids: + self._log.debug( + 'Token is marked as having been revoked by audit id') + raise exc.InvalidToken(_('Token has been revoked')) |