Merge "Use hashed token for invalid PKI token cache key"

This commit is contained in:
Jenkins
2013-08-26 20:02:10 +00:00
committed by Gerrit Code Review
2 changed files with 33 additions and 21 deletions

View File

@@ -774,6 +774,8 @@ class AuthProtocol(object):
:no longer raises ServiceError since it no longer makes RPC :no longer raises ServiceError since it no longer makes RPC
""" """
token_id = None
try: try:
token_id = cms.cms_hash_token(user_token) token_id = cms.cms_hash_token(user_token)
cached = self._cache_get(token_id) cached = self._cache_get(token_id)
@@ -789,12 +791,13 @@ class AuthProtocol(object):
return data return data
except NetworkError as e: except NetworkError as e:
self.LOG.debug('Token validation failure.', exc_info=True) self.LOG.debug('Token validation failure.', exc_info=True)
self.LOG.warn("Authorization failed for token %s", user_token) self.LOG.warn("Authorization failed for token %s", token_id)
raise InvalidUserToken('Token authorization failed') raise InvalidUserToken('Token authorization failed')
except Exception as e: except Exception as e:
self.LOG.debug('Token validation failure.', exc_info=True) self.LOG.debug('Token validation failure.', exc_info=True)
self._cache_store_invalid(user_token) if token_id:
self.LOG.warn("Authorization failed for token %s", user_token) self._cache_store_invalid(token_id)
self.LOG.warn("Authorization failed for token %s", token_id)
raise InvalidUserToken('Token authorization failed') raise InvalidUserToken('Token authorization failed')
def _token_is_v2(self, token_info): def _token_is_v2(self, token_info):
@@ -935,20 +938,20 @@ class AuthProtocol(object):
env_key = self._header_to_env_var(key) env_key = self._header_to_env_var(key)
return env.get(env_key, default) return env.get(env_key, default)
def _cache_get(self, token, ignore_expires=False): def _cache_get(self, token_id, ignore_expires=False):
"""Return token information from cache. """Return token information from cache.
If token is invalid raise InvalidUserToken If token is invalid raise InvalidUserToken
return token only if fresh (not expired). return token only if fresh (not expired).
""" """
if self._cache and token: if self._cache and token_id:
if self._memcache_security_strategy is None: if self._memcache_security_strategy is None:
key = CACHE_KEY_TEMPLATE % token key = CACHE_KEY_TEMPLATE % token_id
serialized = self._cache.get(key) serialized = self._cache.get(key)
else: else:
keys = memcache_crypt.derive_keys( keys = memcache_crypt.derive_keys(
token, token_id,
self._memcache_secret_key, self._memcache_secret_key,
self._memcache_security_strategy) self._memcache_security_strategy)
cache_key = CACHE_KEY_TEMPLATE % ( cache_key = CACHE_KEY_TEMPLATE % (
@@ -973,17 +976,18 @@ class AuthProtocol(object):
# a collision with json.loads(serialized) == None. # a collision with json.loads(serialized) == None.
cached = json.loads(serialized) cached = json.loads(serialized)
if cached == 'invalid': if cached == 'invalid':
self.LOG.debug('Cached Token %s is marked unauthorized', token) self.LOG.debug('Cached Token %s is marked unauthorized',
token_id)
raise InvalidUserToken('Token authorization failed') raise InvalidUserToken('Token authorization failed')
data, expires = cached data, expires = cached
if ignore_expires or time.time() < float(expires): if ignore_expires or time.time() < float(expires):
self.LOG.debug('Returning cached token %s', token) self.LOG.debug('Returning cached token %s', token_id)
return data return data
else: else:
self.LOG.debug('Cached Token %s seems expired', token) self.LOG.debug('Cached Token %s seems expired', token_id)
def _cache_store(self, token, data): def _cache_store(self, token_id, data):
"""Store value into memcache. """Store value into memcache.
data may be the string 'invalid' or a tuple like (data, expires) data may be the string 'invalid' or a tuple like (data, expires)
@@ -991,11 +995,11 @@ class AuthProtocol(object):
""" """
serialized_data = json.dumps(data) serialized_data = json.dumps(data)
if self._memcache_security_strategy is None: if self._memcache_security_strategy is None:
cache_key = CACHE_KEY_TEMPLATE % token cache_key = CACHE_KEY_TEMPLATE % token_id
data_to_store = serialized_data data_to_store = serialized_data
else: else:
keys = memcache_crypt.derive_keys( keys = memcache_crypt.derive_keys(
token, token_id,
self._memcache_secret_key, self._memcache_secret_key,
self._memcache_security_strategy) self._memcache_security_strategy)
cache_key = CACHE_KEY_TEMPLATE % memcache_crypt.get_cache_key(keys) cache_key = CACHE_KEY_TEMPLATE % memcache_crypt.get_cache_key(keys)
@@ -1030,7 +1034,7 @@ class AuthProtocol(object):
raise InvalidUserToken('Token authorization failed') raise InvalidUserToken('Token authorization failed')
return expires return expires
def _cache_put(self, token, data, expires): def _cache_put(self, token_id, data, expires):
"""Put token data into the cache. """Put token data into the cache.
Stores the parsed expire date in cache allowing Stores the parsed expire date in cache allowing
@@ -1038,15 +1042,15 @@ class AuthProtocol(object):
""" """
if self._cache: if self._cache:
self.LOG.debug('Storing %s token in memcache', token) self.LOG.debug('Storing %s token in memcache', token_id)
self._cache_store(token, (data, expires)) self._cache_store(token_id, (data, expires))
def _cache_store_invalid(self, token): def _cache_store_invalid(self, token_id):
"""Store invalid token in cache.""" """Store invalid token in cache."""
if self._cache: if self._cache:
self.LOG.debug( self.LOG.debug(
'Marking token %s as unauthorized in memcache', token) 'Marking token %s as unauthorized in memcache', token_id)
self._cache_store(token, 'invalid') self._cache_store(token_id, 'invalid')
def cert_file_missing(self, proc_output, file_name): def cert_file_missing(self, proc_output, file_name):
return (file_name in proc_output and not os.path.exists(file_name)) return (file_name in proc_output and not os.path.exists(file_name))

View File

@@ -812,9 +812,17 @@ class AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest):
self.middleware(req.environ, self.start_fake_response) self.middleware(req.environ, self.start_fake_response)
self.assertEqual(self.response_status, 401) self.assertEqual(self.response_status, 401)
def test_memcache_set_invalid(self): def test_memcache_set_invalid_uuid(self):
req = webob.Request.blank('/') req = webob.Request.blank('/')
token = 'invalid-token' token = uuid.uuid4().hex
req.headers['X-Auth-Token'] = token
self.middleware(req.environ, self.start_fake_response)
self.assertRaises(auth_token.InvalidUserToken,
self._get_cached_token, token)
def test_memcache_set_invalid_signed(self):
req = webob.Request.blank('/')
token = self.token_dict['signed_token_scoped_expired']
req.headers['X-Auth-Token'] = token req.headers['X-Auth-Token'] = token
self.middleware(req.environ, self.start_fake_response) self.middleware(req.environ, self.start_fake_response)
self.assertRaises(auth_token.InvalidUserToken, self.assertRaises(auth_token.InvalidUserToken,