summaryrefslogtreecommitdiffstats
path: root/keystonemiddleware-moon/keystonemiddleware/auth_token
diff options
context:
space:
mode:
authorasteroide <thomas.duval@orange.com>2016-03-04 15:50:10 +0100
committerasteroide <thomas.duval@orange.com>2016-03-04 15:50:10 +0100
commit65ab65faac57b156c4d238afa8de422f52a5a68a (patch)
tree34bc68621f261c9cba4153d5ef9a2ff2ef6449a4 /keystonemiddleware-moon/keystonemiddleware/auth_token
parent7be2f3dfff8541051c641e5715d6d70705cab5f7 (diff)
Update KeystoneMiddleware to the stable/liberty version.
Change-Id: I225ed685dad129dc7c1d5d6a00e54c0facde0c07
Diffstat (limited to 'keystonemiddleware-moon/keystonemiddleware/auth_token')
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py44
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py17
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py22
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'))