diff options
author | Jamie Lennox <jlennox@redhat.com> | 2013-06-17 04:22:06 +0000 |
---|---|---|
committer | Jamie Lennox <jamielennox@gmail.com> | 2013-07-17 15:37:14 +1000 |
commit | 2667c772a30c16ca147f8e38143b59ac53ec5b0c (patch) | |
tree | a0765296b56be440847fa856382f79eed216714f /keystone/token | |
parent | 53a03b53e7541367c07df6d4f6739173330f5353 (diff) | |
download | keystone-2667c772a30c16ca147f8e38143b59ac53ec5b0c.tar.gz keystone-2667c772a30c16ca147f8e38143b59ac53ec5b0c.tar.xz keystone-2667c772a30c16ca147f8e38143b59ac53ec5b0c.zip |
Implement Token Binding.
Brings token binding to keystone server. There are a number of places
where the location or hardcoding of binding checks are not optimal
however fixing them will require having a proper authentication plugin
scheme so just assume that they will be moved when that happens.
DocImpact
Implements: blueprint authentication-tied-to-token
Change-Id: Ib34e5e0b6bd83837f6addbd45d4c5b828ce2f3bd
Diffstat (limited to 'keystone/token')
-rw-r--r-- | keystone/token/controllers.py | 20 | ||||
-rw-r--r-- | keystone/token/providers/uuid.py | 11 |
2 files changed, 26 insertions, 5 deletions
diff --git a/keystone/token/controllers.py b/keystone/token/controllers.py index 7a5b9be3..d2b7d9fd 100644 --- a/keystone/token/controllers.py +++ b/keystone/token/controllers.py @@ -5,6 +5,7 @@ from keystone.common import controller from keystone.common import dependency from keystone.common import logging from keystone.common import utils +from keystone.common import wsgi from keystone import config from keystone import exception from keystone.openstack.common import timeutils @@ -78,7 +79,7 @@ class Auth(controller.V2Controller): auth_info = self._authenticate_local( context, auth) - user_ref, tenant_ref, metadata_ref, expiry = auth_info + user_ref, tenant_ref, metadata_ref, expiry, bind = auth_info core.validate_auth_info(self, user_ref, tenant_ref) user_ref = self._filter_domain_id(user_ref) if tenant_ref: @@ -97,6 +98,8 @@ class Auth(controller.V2Controller): catalog_ref = {} auth_token_data['id'] = 'placeholder' + if bind: + auth_token_data['bind'] = bind roles_ref = [] for role_id in metadata_ref.get('roles', []): @@ -133,6 +136,8 @@ class Auth(controller.V2Controller): except exception.NotFound as e: raise exception.Unauthorized(e) + wsgi.validate_token_bind(context, old_token_ref) + #A trust token cannot be used to get another token if 'trust' in old_token_ref: raise exception.Forbidden() @@ -194,7 +199,9 @@ class Auth(controller.V2Controller): metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id - return (current_user_ref, tenant_ref, metadata_ref, expiry) + bind = old_token_ref.get('bind', None) + + return (current_user_ref, tenant_ref, metadata_ref, expiry, bind) def _authenticate_local(self, context, auth): """Try to authenticate against the identity backend. @@ -252,7 +259,7 @@ class Auth(controller.V2Controller): user_id, tenant_id) expiry = core.default_expire_time() - return (user_ref, tenant_ref, metadata_ref, expiry) + return (user_ref, tenant_ref, metadata_ref, expiry, None) def _authenticate_external(self, context, auth): """Try to authenticate an external user via REMOTE_USER variable. @@ -281,7 +288,12 @@ class Auth(controller.V2Controller): user_id, tenant_id) expiry = core.default_expire_time() - return (user_ref, tenant_ref, metadata_ref, expiry) + bind = None + if ('kerberos' in CONF.token.bind and + context.get('AUTH_TYPE', '').lower() == 'negotiate'): + bind = {'kerberos': username} + + return (user_ref, tenant_ref, metadata_ref, expiry, bind) def _get_auth_token_data(self, user, tenant, metadata, expiry): return dict(user=user, diff --git a/keystone/token/providers/uuid.py b/keystone/token/providers/uuid.py index aff738f0..1d49473b 100644 --- a/keystone/token/providers/uuid.py +++ b/keystone/token/providers/uuid.py @@ -59,6 +59,8 @@ class V2TokenDataHelper(object): } } } + if 'bind' in token_ref: + o['access']['token']['bind'] = token_ref['bind'] if 'tenant' in token_ref and token_ref['tenant']: token_ref['tenant']['enabled'] = True o['access']['token']['tenant'] = token_ref['tenant'] @@ -285,7 +287,8 @@ class V3TokenDataHelper(object): def get_token_data(self, user_id, method_names, extras, domain_id=None, project_id=None, expires=None, - trust=None, token=None, include_catalog=True): + trust=None, token=None, include_catalog=True, + bind=None): token_data = {'methods': method_names, 'extras': extras} @@ -299,6 +302,9 @@ class V3TokenDataHelper(object): if user_id != trust['trustee_user_id']: raise exception.Forbidden(_('User is not a trustee.')) + if bind: + token_data['bind'] = bind + self._populate_scope(token_data, domain_id, project_id) self._populate_user(token_data, user_id, domain_id, project_id, trust) self._populate_roles(token_data, user_id, domain_id, project_id, trust) @@ -346,6 +352,7 @@ class Provider(token.provider.Provider): tenant=token_ref['tenant'], metadata=token_ref['metadata'], token_data=token_data, + bind=token_ref.get('bind'), trust_id=token_ref['metadata'].get('trust_id')) self.token_api.create_token(token_id, data) except Exception: @@ -381,6 +388,7 @@ class Provider(token.provider.Provider): project_id=project_id, expires=expires_at, trust=trust, + bind=auth_context.get('bind') if auth_context else None, include_catalog=include_catalog) token_id = self._get_token_id(token_data) @@ -542,6 +550,7 @@ class Provider(token.provider.Provider): ['password', 'token'], {}, project_id=project_id, + bind=token_ref.get('bind'), expires=token_ref['expires']) return token_data |