summaryrefslogtreecommitdiffstats
path: root/keystone/middleware
diff options
context:
space:
mode:
authorJoe Heck <heckj@mac.com>2012-11-01 15:36:31 -0700
committerVishvananda Ishaya <vishvananda@gmail.com>2012-11-07 20:09:22 -0800
commit7cc02c80cfb1976271fa8b6271091fcd35c1cb34 (patch)
treeeeaf2187cfd57f61b26f684fc1e52eb6c1e5cb43 /keystone/middleware
parent8ee69635066129b0029d61c4b8248420f994290e (diff)
downloadkeystone-7cc02c80cfb1976271fa8b6271091fcd35c1cb34.tar.gz
keystone-7cc02c80cfb1976271fa8b6271091fcd35c1cb34.tar.xz
keystone-7cc02c80cfb1976271fa8b6271091fcd35c1cb34.zip
fixes bug 1074172
updated diablo token based on output from diablo/stable keystone added expiry to example tokens for test_auth_middleware added a stack based HTTP response to test_auth_middleware to verify sequencing Change-Id: I738b0e9c1a0e62ad86adb95ec0b73f621513f7d4
Diffstat (limited to 'keystone/middleware')
-rw-r--r--keystone/middleware/auth_token.py38
1 files changed, 35 insertions, 3 deletions
diff --git a/keystone/middleware/auth_token.py b/keystone/middleware/auth_token.py
index 5c198e83..43261f29 100644
--- a/keystone/middleware/auth_token.py
+++ b/keystone/middleware/auth_token.py
@@ -159,6 +159,16 @@ opts = [
CONF.register_opts(opts, group='keystone_authtoken')
+def will_expire_soon(expiry):
+ """ Determines if expiration is about to occur.
+
+ :param expiry: a datetime of the expected expiration
+ :returns: boolean : true if expiration is within 30 seconds
+ """
+ soon = (timeutils.utcnow() + datetime.timedelta(seconds=30))
+ return expiry < soon
+
+
class InvalidUserToken(Exception):
pass
@@ -230,6 +240,7 @@ class AuthProtocol(object):
# Credentials used to verify this component with the Auth service since
# validating tokens is a privileged call
self.admin_token = self._conf_get('admin_token')
+ self.admin_token_expiry = None
self.admin_user = self._conf_get('admin_user')
self.admin_password = self._conf_get('admin_password')
self.admin_tenant_name = self._conf_get('admin_tenant_name')
@@ -345,12 +356,21 @@ class AuthProtocol(object):
def get_admin_token(self):
"""Return admin token, possibly fetching a new one.
+ if self.admin_token_expiry is set from fetching an admin token, check
+ it for expiration, and request a new token is the existing token
+ is about to expire.
+
:return admin token id
:raise ServiceError when unable to retrieve token from keystone
"""
+ if self.admin_token_expiry:
+ if will_expire_soon(self.admin_token_expiry):
+ self.admin_token = None
+
if not self.admin_token:
- self.admin_token = self._request_admin_token()
+ (self.admin_token,
+ self.admin_token_expiry) = self._request_admin_token()
return self.admin_token
@@ -455,11 +475,17 @@ class AuthProtocol(object):
try:
token = data['access']['token']['id']
+ expiry = data['access']['token']['expires']
assert token
- return token
+ assert expiry
+ datetime_expiry = timeutils.parse_isotime(expiry)
+ return (token, timeutils.normalize_time(datetime_expiry))
except (AssertionError, KeyError):
LOG.warn("Unexpected response from keystone service: %s", data)
raise ServiceError('invalid json response')
+ except (ValueError):
+ LOG.warn("Unable to parse expiration time from token: %s", data)
+ raise ServiceError('invalid json response')
def _validate_user_token(self, user_token, retry=True):
"""Authenticate user using PKI
@@ -771,10 +797,16 @@ class AuthProtocol(object):
with open(self.revoked_file_name, 'w') as f:
f.write(value)
- def fetch_revocation_list(self):
+ def fetch_revocation_list(self, retry=True):
headers = {'X-Auth-Token': self.get_admin_token()}
response, data = self._json_request('GET', '/v2.0/tokens/revoked',
additional_headers=headers)
+ if response.status == 401:
+ if retry:
+ LOG.info('Keystone rejected admin token %s, resetting admin '
+ 'token', headers)
+ self.admin_token = None
+ return self.fetch_revocation_list(retry=False)
if response.status != 200:
raise ServiceError('Unable to fetch token revocation list.')
if (not 'signed' in data):