def _build_policy_check_credentials(self, action, context, kwargs): kwargs_str = ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs]) kwargs_str = strutils.mask_password(kwargs_str) LOG.debug('RBAC: Authorizing %(action)s(%(kwargs)s)', { 'action': action, 'kwargs': kwargs_str}) # see if auth context has already been created. If so use it. if ('environment' in context and authorization.AUTH_CONTEXT_ENV in context['environment']): LOG.debug('RBAC: using auth context from the request environment') return context['environment'].get(authorization.AUTH_CONTEXT_ENV) # There is no current auth context, build it from the incoming token. # TODO(morganfainberg): Collapse this logic with AuthContextMiddleware # in a sane manner as this just mirrors the logic in AuthContextMiddleware try: LOG.debug('RBAC: building auth context from the incoming auth token') token_ref = token_model.KeystoneToken( token_id=context['token_id'], token_data=self.token_provider_api.validate_token( context['token_id'])) # NOTE(jamielennox): whilst this maybe shouldn't be within this # function it would otherwise need to reload the token_ref from # backing store. wsgi.validate_token_bind(context, token_ref) except exception.TokenNotFound: LOG.warning(_LW('RBAC: Invalid token')) raise exception.Unauthorized() auth_context = authorization.token_to_auth_context(token_ref) return auth_context
def _build_auth_context(self, request): token_id = request.headers.get(AUTH_TOKEN_HEADER).strip() if token_id == CONF.admin_token: # NOTE(gyee): no need to proceed any further as the special admin # token is being handled by AdminTokenAuthMiddleware. This code # will not be impacted even if AdminTokenAuthMiddleware is removed # from the pipeline as "is_admin" is default to "False". This code # is independent of AdminTokenAuthMiddleware. return {} context = {'token_id': token_id} context['environment'] = request.environ try: token_ref = token_model.KeystoneToken( token_id=token_id, token_data=self.token_provider_api.validate_token(token_id)) # TODO(gyee): validate_token_bind should really be its own # middleware wsgi.validate_token_bind(context, token_ref) return authorization.token_to_auth_context(token_ref) except exception.TokenNotFound: LOG.warning(_LW('RBAC: Invalid token')) raise exception.Unauthorized()
def authenticate(self, context, auth_payload, user_context): try: if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target=METHOD_NAME) token_id = auth_payload['id'] token_ref = self.token_api.get_token(token_id) if ('OS-TRUST:trust' in token_ref['token_data']['token'] or 'trust' in token_ref['token_data']['token']): raise exception.Forbidden() if 'OS-OAUTH1' in token_ref['token_data']['token']: raise exception.Forbidden() wsgi.validate_token_bind(context, token_ref) user_context.setdefault( 'user_id', token_ref['token_data']['token']['user']['id']) # to support Grizzly-3 to Grizzly-RC1 transition expires_at = token_ref['token_data']['token'].get( 'expires_at', token_ref['token_data']['token'].get('expires')) user_context.setdefault('expires_at', expires_at) user_context['extras'].update( token_ref['token_data']['token']['extras']) user_context['method_names'].extend( token_ref['token_data']['token']['methods']) except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def token_authenticate(context, auth_payload, user_context, token_ref): try: if not CONF.token.allow_rescope_scoped_token: # Do not allow conversion from scoped tokens. if token_ref.project_scoped or token_ref.domain_scoped: raise exception.Forbidden(action=_("rescope a scoped token")) wsgi.validate_token_bind(context, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None user_context.setdefault('expires_at', token_ref.expires) user_context['audit_id'] = token_audit_id user_context.setdefault('user_id', token_ref.user_id) # TODO(morganfainberg: determine if token 'extras' can be removed # from the user_context user_context['extras'].update(token_ref.get('extras', {})) user_context['method_names'].extend(token_ref.methods) except AssertionError as e: LOG.error(six.text_type(e)) raise exception.Unauthorized(e)
def assert_kerberos_bind(self, tokens, bind_level, use_kerberos=True, success=True): if not isinstance(tokens, dict): for token in tokens: self.assert_kerberos_bind(token, bind_level, use_kerberos=use_kerberos, success=success) elif use_kerberos == ANY: for val in (True, False): self.assert_kerberos_bind(tokens, bind_level, use_kerberos=val, success=success) else: context = {'environment': {}} self.config_fixture.config(group='token', enforce_token_bind=bind_level) if use_kerberos: context['environment']['REMOTE_USER'] = KERBEROS_BIND context['environment']['AUTH_TYPE'] = 'Negotiate' # NOTE(morganfainberg): This assumes a V3 token. token_ref = token_model.KeystoneToken(token_id=uuid.uuid4().hex, token_data=tokens) if not success: self.assertRaises(exception.Unauthorized, wsgi.validate_token_bind, context, token_ref) else: wsgi.validate_token_bind(context, token_ref)
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug( "RBAC: Authorizing %(action)s(%(kwargs)s)", {"action": action, "kwargs": ", ".join(["%s=%s" % (k, kwargs[k]) for k in kwargs])}, ) # see if auth context has already been created. If so use it. if "environment" in context and authorization.AUTH_CONTEXT_ENV in context["environment"]: LOG.debug("RBAC: using auth context from the request environment") return context["environment"].get(authorization.AUTH_CONTEXT_ENV) # There is no current auth context, build it from the incoming token. # TODO(morganfainberg): Collapse this logic with AuthContextMiddleware # in sane manner as this just mirrors the logic in AuthContextMiddleware try: LOG.debug("RBAC: building auth context from the incoming auth token") token_ref = token_model.KeystoneToken( token_id=context["token_id"], token_data=self.token_provider_api.validate_token(context["token_id"]) ) # NOTE(jamielennox): whilst this maybe shouldn't be within this # function it would otherwise need to reload the token_ref from # backing store. wsgi.validate_token_bind(context, token_ref) except exception.TokenNotFound: LOG.warning(_("RBAC: Invalid token")) raise exception.Unauthorized() auth_context = authorization.token_to_auth_context(token_ref) return auth_context
def _build_policy_check_credentials(self, action, context, kwargs): kwargs_str = ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs]) kwargs_str = strutils.mask_password(kwargs_str) LOG.debug('RBAC: Authorizing %(action)s(%(kwargs)s)', { 'action': action, 'kwargs': kwargs_str }) # see if auth context has already been created. If so use it. if ('environment' in context and authorization.AUTH_CONTEXT_ENV in context['environment']): LOG.debug('RBAC: using auth context from the request environment') return context['environment'].get(authorization.AUTH_CONTEXT_ENV) # There is no current auth context, build it from the incoming token. # TODO(morganfainberg): Collapse this logic with AuthContextMiddleware # in a sane manner as this just mirrors the logic in AuthContextMiddleware try: LOG.debug('RBAC: building auth context from the incoming auth token') token_ref = token_model.KeystoneToken( token_id=context['token_id'], token_data=self.token_provider_api.validate_token( context['token_id'])) # NOTE(jamielennox): whilst this maybe shouldn't be within this # function it would otherwise need to reload the token_ref from # backing store. wsgi.validate_token_bind(context, token_ref) except exception.TokenNotFound: LOG.warning(_LW('RBAC: Invalid token')) raise exception.Unauthorized() auth_context = authorization.token_to_auth_context(token_ref) return auth_context
def _build_auth_context(self, request): token_id = request.headers.get(AUTH_TOKEN_HEADER).strip() if token_id == CONF.admin_token: # NOTE(gyee): no need to proceed any further as the special admin # token is being handled by AdminTokenAuthMiddleware. This code # will not be impacted even if AdminTokenAuthMiddleware is removed # from the pipeline as "is_admin" is default to "False". This code # is independent of AdminTokenAuthMiddleware. return {} context = {'token_id': token_id} context['environment'] = request.environ try: token_ref = token_model.KeystoneToken( token_id=token_id, token_data=self.token_provider_api.validate_token(token_id)) # TODO(gyee): validate_token_bind should really be its own # middleware wsgi.validate_token_bind(context, token_ref) return authorization.token_to_auth_context(token_ref) except exception.TokenNotFound: LOG.warning(_LW('RBAC: Invalid token')) raise exception.Unauthorized()
def _build_token_auth_context(self, request, token_id): if CONF.admin_token and token_id == CONF.admin_token: versionutils.report_deprecated_feature( LOG, _LW('build_auth_context middleware checking for the admin ' 'token is deprecated as of the Mitaka release and will be ' 'removed in the O release. If your deployment requires ' 'use of the admin token, update keystone-paste.ini so ' 'that admin_token_auth is before build_auth_context in ' 'the paste pipelines, otherwise remove the ' 'admin_token_auth middleware from the paste pipelines.')) return {}, True context = {'token_id': token_id} context['environment'] = request.environ try: token_ref = token_model.KeystoneToken( token_id=token_id, token_data=self.token_provider_api.validate_token(token_id)) # TODO(gyee): validate_token_bind should really be its own # middleware wsgi.validate_token_bind(context, token_ref) return authorization.token_to_auth_context(token_ref), False except exception.TokenNotFound: LOG.warning(_LW('RBAC: Invalid token')) raise exception.Unauthorized()
def _build_token_auth_context(self, request, token_id): if CONF.admin_token and token_id == CONF.admin_token: versionutils.report_deprecated_feature( LOG, _LW('build_auth_context middleware checking for the admin ' 'token is deprecated as of the Mitaka release and will be ' 'removed in the O release. If your deployment requires ' 'use of the admin token, update keystone-paste.ini so ' 'that admin_token_auth is before build_auth_context in ' 'the paste pipelines, otherwise remove the ' 'admin_token_auth middleware from the paste pipelines.')) return {}, True context = {'token_id': token_id} context['environment'] = request.environ try: token_ref = token_model.KeystoneToken( token_id=token_id, token_data=self.token_provider_api.validate_token(token_id)) # TODO(gyee): validate_token_bind should really be its own # middleware wsgi.validate_token_bind(context, token_ref) return authorization.token_to_auth_context(token_ref), False except exception.TokenNotFound: LOG.warning(_LW('RBAC: Invalid token')) raise exception.Unauthorized()
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug( 'RBAC: Authorizing %(action)s(%(kwargs)s)', { 'action': action, 'kwargs': ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs]) }) # see if auth context has already been created. If so use it. if ('environment' in context and authorization.AUTH_CONTEXT_ENV in context['environment']): LOG.debug('RBAC: using auth context from the request environment') return context['environment'].get(authorization.AUTH_CONTEXT_ENV) # now build the auth context from the incoming auth token try: LOG.debug('RBAC: building auth context from the incoming auth token') # TODO(ayoung): These two functions return the token in different # formats. However, the call # to get_token hits the caching layer, and does not validate the # token. This should be reduced to one call if not CONF.token.revoke_by_id: self.token_api.token_provider_api.validate_token( context['token_id']) token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) auth_context = authorization.token_to_auth_context(token_ref['token_data']) return auth_context
def _build_auth_context(self, request): token_id = request.headers.get(AUTH_TOKEN_HEADER) if token_id == CONF.admin_token: # NOTE(gyee): no need to proceed any further as the special admin # token is being handled by AdminTokenAuthMiddleware. This code # will not be impacted even if AdminTokenAuthMiddleware is removed # from the pipeline as "is_admin" is default to "False". This code # is independent of AdminTokenAuthMiddleware. return {} context = {'token_id': token_id} context['environment'] = request.environ try: token_ref = self.token_api.get_token(token_id) # TODO(ayoung): These two functions return the token in different # formats instead of two calls, only make one. However, the call # to get_token hits the caching layer, and does not validate the # token. In the future, this should be reduced to one call. if not CONF.token.revoke_by_id: self.token_api.token_provider_api.validate_token( context['token_id']) # TODO(gyee): validate_token_bind should really be its own # middleware wsgi.validate_token_bind(context, token_ref) return authorization.token_to_auth_context( token_ref['token_data']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized()
def assert_kerberos_bind(self, tokens, bind_level, use_kerberos=True, success=True): if not isinstance(tokens, dict): for token in tokens: self.assert_kerberos_bind(token, bind_level, use_kerberos=use_kerberos, success=success) elif use_kerberos == ANY: for val in (True, False): self.assert_kerberos_bind(tokens, bind_level, use_kerberos=val, success=success) else: context = {} CONF.token.enforce_token_bind = bind_level if use_kerberos: context['REMOTE_USER'] = KERBEROS_BIND context['AUTH_TYPE'] = 'Negotiate' if not success: self.assertRaises(exception.Unauthorized, wsgi.validate_token_bind, context, tokens) else: wsgi.validate_token_bind(context, tokens)
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug('RBAC: Authorizing %(action)s(%(kwargs)s)', { 'action': action, 'kwargs': ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs])}) # see if auth context has already been created. If so use it. if ('environment' in context and authorization.AUTH_CONTEXT_ENV in context['environment']): LOG.debug('RBAC: using auth context from the request environment') return context['environment'].get(authorization.AUTH_CONTEXT_ENV) # now build the auth context from the incoming auth token try: LOG.debug('RBAC: building auth context from the incoming auth token') # TODO(ayoung): These two functions return the token in different # formats. However, the call # to get_token hits the caching layer, and does not validate the # token. This should be reduced to one call if not CONF.token.revoke_by_id: self.token_api.token_provider_api.validate_token( context['token_id']) token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) auth_context = authorization.token_to_auth_context(token_ref['token_data']) return auth_context
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug( _('RBAC: Authorizing %(action)s(%(kwargs)s)'), { 'action': action, 'kwargs': ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs]) }) # see if auth context has already been created. If so use it. if ('environment' in context and authorization.AUTH_CONTEXT_ENV in context['environment']): LOG.debug(_('RBAC: using auth context from the request environment')) return context['environment'].get(authorization.AUTH_CONTEXT_ENV) # now build the auth context from the incoming auth token try: LOG.debug( _('RBAC: building auth context from the incoming ' 'auth token')) token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) auth_context = authorization.token_to_auth_context(token_ref['token_data']) return auth_context
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug(_('RBAC: Authorizing %(action)s(%(kwargs)s)'), { 'action': action, 'kwargs': ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs])}) # see if auth context has already been created. If so use it. if ('environment' in context and authorization.AUTH_CONTEXT_ENV in context['environment']): LOG.debug(_('RBAC: using auth context from the request environment')) return context['environment'].get(authorization.AUTH_CONTEXT_ENV) # now build the auth context from the incoming auth token try: LOG.debug(_('RBAC: building auth context from the incoming ' 'auth token')) token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) auth_context = authorization.token_to_auth_context(token_ref['token_data']) return auth_context
def assert_kerberos_bind(self, tokens, bind_level, use_kerberos=True, success=True): if not isinstance(tokens, dict): for token in tokens: self.assert_kerberos_bind(token, bind_level, use_kerberos=use_kerberos, success=success) elif use_kerberos == ANY: for val in (True, False): self.assert_kerberos_bind(tokens, bind_level, use_kerberos=val, success=success) else: context = {'environment': {}} self.config_fixture.config(group='token', enforce_token_bind=bind_level) if use_kerberos: context['environment']['REMOTE_USER'] = KERBEROS_BIND context['environment']['AUTH_TYPE'] = 'Negotiate' # NOTE(morganfainberg): This assumes a V3 token. token_ref = token_model.KeystoneToken( token_id=uuid.uuid4().hex, token_data=tokens) if not success: self.assertRaises(exception.Unauthorized, wsgi.validate_token_bind, context, token_ref) else: wsgi.validate_token_bind(context, token_ref)
def _build_auth_context(self, request): token_id = request.headers.get(AUTH_TOKEN_HEADER) if token_id == CONF.admin_token: # NOTE(gyee): no need to proceed any further as the special admin # token is being handled by AdminTokenAuthMiddleware. This code # will not be impacted even if AdminTokenAuthMiddleware is removed # from the pipeline as "is_admin" is default to "False". This code # is independent of AdminTokenAuthMiddleware. return {} context = {'token_id': token_id} context['environment'] = request.environ try: token_ref = self.token_api.get_token(token_id) # TODO(ayoung): These two functions return the token in different # formats instead of two calls, only make one. However, the call # to get_token hits the caching layer, and does not validate the # token. In the future, this should be reduced to one call. if not CONF.token.revoke_by_id: self.token_api.token_provider_api.validate_token( context['token_id']) # TODO(gyee): validate_token_bind should really be its own # middleware wsgi.validate_token_bind(context, token_ref) return authorization.token_to_auth_context(token_ref['token_data']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized()
def authenticate(self, context, auth_payload, user_context): try: if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target=self.method) token_id = auth_payload['id'] response = self.token_provider_api.validate_token(token_id) # For V3 tokens, the essential data is under the 'token' value. # For V2, the comparable data was nested under 'access'. token_ref = response.get('token', response.get('access')) # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if 'OS-TRUST:trust' in token_ref: raise exception.Forbidden() if 'trust' in token_ref: raise exception.Forbidden() if 'trust_id' in token_ref.get('metadata', {}): raise exception.Forbidden() if 'OS-OAUTH1' in token_ref: raise exception.Forbidden() wsgi.validate_token_bind(context, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None # New tokens are not allowed to extend the expiration # time of an old token, otherwise, they could be extened # forever. The expiration value was stored at different # locations in v2 and v3 tokens. expires_at = token_ref.get('expires_at') if not expires_at: expires_at = token_ref.get('expires') if not expires_at: expires_at = timeutils.normalize_time( timeutils.parse_isotime(token_ref['token']['expires'])) user_context.setdefault('expires_at', expires_at) user_context['audit_id'] = token_audit_id user_context.setdefault('user_id', token_ref['user']['id']) user_context['extras'].update(token_ref.get('extras', {})) user_context['method_names'].extend(token_ref.get('methods', [])) except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def token_authenticate(request, token_ref): response_data = {} try: # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if token_ref.oauth_scoped: raise exception.ForbiddenAction( action=_( 'Using OAuth-scoped token to create another token. ' 'Create a new OAuth-scoped token instead')) elif token_ref.trust_scoped: raise exception.ForbiddenAction( action=_( 'Using trust-scoped token to create another token. ' 'Create a new trust-scoped token instead')) if not CONF.token.allow_rescope_scoped_token: # Do not allow conversion from scoped tokens. if token_ref.project_scoped or token_ref.domain_scoped: raise exception.ForbiddenAction( action=_('rescope a scoped token')) wsgi.validate_token_bind(request.context_dict, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None # To prevent users from never having to re-authenticate, the original # token expiration time is maintained in the new token. Not doing this # would make it possible for a user to continuously bump token # expiration through token rescoping without proving their identity. response_data.setdefault('expires_at', token_ref.expires) response_data['audit_id'] = token_audit_id response_data.setdefault('user_id', token_ref.user_id) # TODO(morganfainberg: determine if token 'extras' can be removed # from the response_data response_data.setdefault('extras', {}).update( token_ref.get('extras', {})) return response_data except AssertionError as e: LOG.error(six.text_type(e)) raise exception.Unauthorized(e)
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug( _('RBAC: Authorizing %(action)s(%(kwargs)s)') % { 'action': action, 'kwargs': ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs]) }) try: token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) creds = {} if 'token_data' in token_ref and 'token' in token_ref['token_data']: #V3 Tokens token_data = token_ref['token_data']['token'] try: creds['user_id'] = token_data['user']['id'] except AttributeError: LOG.warning(_('RBAC: Invalid user')) raise exception.Unauthorized() if 'project' in token_data: creds['project_id'] = token_data['project']['id'] else: LOG.debug(_('RBAC: Proceeding without project')) if 'domain' in token_data: creds['domain_id'] = token_data['domain']['id'] if 'roles' in token_data: creds['roles'] = [] for role in token_data['roles']: creds['roles'].append(role['name']) else: #v2 Tokens creds = token_ref.get('metadata', {}).copy() try: creds['user_id'] = token_ref['user'].get('id') except AttributeError: LOG.warning(_('RBAC: Invalid user')) raise exception.Unauthorized() try: creds['project_id'] = token_ref['tenant'].get('id') except AttributeError: LOG.debug(_('RBAC: Proceeding without tenant')) # NOTE(vish): this is pretty inefficient creds['roles'] = [ self.assignment_api.get_role(role)['name'] for role in creds.get('roles', []) ] return creds
def token_authenticate(request, token_ref): response_data = {} try: # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if token_ref.oauth_scoped: raise exception.ForbiddenAction( action=_('Using OAuth-scoped token to create another token. ' 'Create a new OAuth-scoped token instead')) elif token_ref.trust_scoped: raise exception.ForbiddenAction( action=_('Using trust-scoped token to create another token. ' 'Create a new trust-scoped token instead')) if not CONF.token.allow_rescope_scoped_token: # Do not allow conversion from scoped tokens. if token_ref.project_scoped or token_ref.domain_scoped: raise exception.ForbiddenAction( action=_('rescope a scoped token')) wsgi.validate_token_bind(request.context_dict, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None response_data.setdefault('expires_at', token_ref.expires) response_data['audit_id'] = token_audit_id response_data.setdefault('user_id', token_ref.user_id) # TODO(morganfainberg: determine if token 'extras' can be removed # from the response_data response_data.setdefault('extras', {}).update(token_ref.get('extras', {})) # NOTE(notmorgan): The Token auth method is *very* special and sets the # previous values to the method_names. This is because it can be used # for re-scoping and we want to maintain the values. Most # AuthMethodHandlers do no such thing and this is not required. response_data.setdefault('method_names', []).extend(token_ref.methods) return response_data except AssertionError as e: LOG.error(six.text_type(e)) raise exception.Unauthorized(e)
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug( _("RBAC: Authorizing %(action)s(%(kwargs)s)"), {"action": action, "kwargs": ", ".join(["%s=%s" % (k, kwargs[k]) for k in kwargs])}, ) try: token_ref = self.token_api.get_token(context["token_id"]) except exception.TokenNotFound: LOG.warning(_("RBAC: Invalid token")) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) creds = {} if "token_data" in token_ref and "token" in token_ref["token_data"]: # V3 Tokens token_data = token_ref["token_data"]["token"] try: creds["user_id"] = token_data["user"]["id"] except AttributeError: LOG.warning(_("RBAC: Invalid user")) raise exception.Unauthorized() if "project" in token_data: creds["project_id"] = token_data["project"]["id"] else: LOG.debug(_("RBAC: Proceeding without project")) if "domain" in token_data: creds["domain_id"] = token_data["domain"]["id"] if "roles" in token_data: creds["roles"] = [] for role in token_data["roles"]: creds["roles"].append(role["name"]) else: # v2 Tokens creds = token_ref.get("metadata", {}).copy() try: creds["user_id"] = token_ref["user"].get("id") except AttributeError: LOG.warning(_("RBAC: Invalid user")) raise exception.Unauthorized() try: creds["project_id"] = token_ref["tenant"].get("id") except AttributeError: LOG.debug(_("RBAC: Proceeding without tenant")) # NOTE(vish): this is pretty inefficient creds["roles"] = [self.assignment_api.get_role(role)["name"] for role in creds.get("roles", [])] return creds
def _build_policy_check_credentials(self, action, context, kwargs): LOG.debug(_('RBAC: Authorizing %(action)s(%(kwargs)s)') % { 'action': action, 'kwargs': ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs])}) try: token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound: LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() # NOTE(jamielennox): whilst this maybe shouldn't be within this function # it would otherwise need to reload the token_ref from backing store. wsgi.validate_token_bind(context, token_ref) creds = {} if 'token_data' in token_ref and 'token' in token_ref['token_data']: #V3 Tokens token_data = token_ref['token_data']['token'] try: creds['user_id'] = token_data['user']['id'] except AttributeError: LOG.warning(_('RBAC: Invalid user')) raise exception.Unauthorized() if 'project' in token_data: creds['project_id'] = token_data['project']['id'] else: LOG.debug(_('RBAC: Proceeding without project')) if 'domain' in token_data: creds['domain_id'] = token_data['domain']['id'] if 'roles' in token_data: creds['roles'] = [] for role in token_data['roles']: creds['roles'].append(role['name']) else: #v2 Tokens creds = token_ref.get('metadata', {}).copy() try: creds['user_id'] = token_ref['user'].get('id') except AttributeError: LOG.warning(_('RBAC: Invalid user')) raise exception.Unauthorized() try: creds['project_id'] = token_ref['tenant'].get('id') except AttributeError: LOG.debug(_('RBAC: Proceeding without tenant')) # NOTE(vish): this is pretty inefficient creds['roles'] = [self.identity_api.get_role(role)['name'] for role in creds.get('roles', [])] return creds
def token_authenticate(request, token_ref): response_data = {} try: # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if token_ref.oauth_scoped: raise exception.ForbiddenAction( action=_( 'Using OAuth-scoped token to create another token. ' 'Create a new OAuth-scoped token instead')) elif token_ref.trust_scoped: raise exception.ForbiddenAction( action=_( 'Using trust-scoped token to create another token. ' 'Create a new trust-scoped token instead')) if not CONF.token.allow_rescope_scoped_token: # Do not allow conversion from scoped tokens. if token_ref.project_scoped or token_ref.domain_scoped: raise exception.ForbiddenAction( action=_('rescope a scoped token')) wsgi.validate_token_bind(request.context_dict, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None response_data.setdefault('expires_at', token_ref.expires) response_data['audit_id'] = token_audit_id response_data.setdefault('user_id', token_ref.user_id) # TODO(morganfainberg: determine if token 'extras' can be removed # from the response_data response_data.setdefault('extras', {}).update( token_ref.get('extras', {})) return response_data except AssertionError as e: LOG.error(six.text_type(e)) raise exception.Unauthorized(e)
def authenticate(self, context, auth_payload, user_context): try: if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target=METHOD_NAME) token_id = auth_payload['id'] response = self.provider.validate_token(token_id) #for V3 tokens, the essential data is under the 'token' value. #For V2, the comparable data was nested under 'access' token_ref = response.get('token', response.get('access')) #Do not allow tokens used for delegation to #create another token, or perform any changes of #state in Keystone. TO do so is to invite elevation of #privilege attacks if 'OS-TRUST:trust' in token_ref: raise exception.Forbidden() if 'trust' in token_ref: raise exception.Forbidden() if 'trust_id' in token_ref.get('metadata', {}): raise exception.Forbidden() if 'OS-OAUTH1' in token_ref: raise exception.Forbidden() wsgi.validate_token_bind(context, token_ref) #new tokens are not allowed to extend the expiration #time of an old token, otherwise, they could be extened #forever. The expiration value was stored at different #locations in v2 and v3 tokens. expires_at = token_ref.get('expires_at') if not expires_at: expires_at = token_ref.get('expires') if not expires_at: expires_at = timeutils.normalize_time( timeutils.parse_isotime(token_ref['token']['expires'])) user_context.setdefault('expires_at', expires_at) user_context.setdefault('user_id', token_ref['user']['id']) user_context['extras'].update(token_ref.get('extras', {})) user_context['method_names'].extend(token_ref.get('methods', [])) except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def authenticate(self, context, auth_payload, user_context): try: if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target=METHOD_NAME) token_id = auth_payload['id'] response = self.provider.validate_token(token_id) #for V3 tokens, the essential data is under the 'token' value. #For V2, the comparable data was nested under 'access' token_ref = response.get('token', response.get('access')) #Do not allow tokens used for delegation to #create another token, or perform any changes of #state in Keystone. TO do so is to invite elevation of #privilege attacks if 'OS-TRUST:trust' in token_ref: raise exception.Forbidden() if 'trust' in token_ref: raise exception.Forbidden() if 'trust_id' in token_ref.get('metadata', {}): raise exception.Forbidden() if 'OS-OAUTH1' in token_ref: raise exception.Forbidden() wsgi.validate_token_bind(context, token_ref) #new tokens are not allowed to extend the expiration #time of an old token, otherwise, they could be extened #forever. The expiration value was stored at different #locations in v2 and v3 tokens. expires_at = token_ref.get('expires_at') if not expires_at: expires_at = token_ref.get('expires') if not expires_at: expires_at = timeutils.normalize_time( timeutils.parse_isotime(token_ref['token']['expires'])) user_context.setdefault('expires_at', expires_at) user_context.setdefault('user_id', token_ref['user']['id']) user_context['extras'].update(token_ref.get('extras', {})) user_context['method_names'].extend(token_ref.get('methods', [])) except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def authenticate(self, context, auth_payload, user_context): try: if "id" not in auth_payload: raise exception.ValidationError(attribute="id", target=self.method) token_id = auth_payload["id"] response = self.token_provider_api.validate_token(token_id) # For V3 tokens, the essential data is under the 'token' value. # For V2, the comparable data was nested under 'access'. token_ref = response.get("token", response.get("access")) # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if "OS-TRUST:trust" in token_ref: raise exception.Forbidden() if "trust" in token_ref: raise exception.Forbidden() if "trust_id" in token_ref.get("metadata", {}): raise exception.Forbidden() if "OS-OAUTH1" in token_ref: raise exception.Forbidden() wsgi.validate_token_bind(context, token_ref) # New tokens are not allowed to extend the expiration # time of an old token, otherwise, they could be extened # forever. The expiration value was stored at different # locations in v2 and v3 tokens. expires_at = token_ref.get("expires_at") if not expires_at: expires_at = token_ref.get("expires") if not expires_at: expires_at = timeutils.normalize_time(timeutils.parse_isotime(token_ref["token"]["expires"])) user_context.setdefault("expires_at", expires_at) user_context.setdefault("user_id", token_ref["user"]["id"]) user_context["extras"].update(token_ref.get("extras", {})) user_context["method_names"].extend(token_ref.get("methods", [])) except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def authenticate(self, context, auth_payload, user_context): try: if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target=self.method) token_id = auth_payload['id'] response = self.token_provider_api.validate_token(token_id) token_ref = token_model.KeystoneToken(token_id=token_id, token_data=response) # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if token_ref.oauth_scoped or token_ref.trust_scoped: raise exception.Forbidden() wsgi.validate_token_bind(context, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None user_context.setdefault('expires_at', token_ref.expires) user_context['audit_id'] = token_audit_id user_context.setdefault('user_id', token_ref.user_id) # TODO(morganfainberg: determine if token 'extras' can be removed # from the user_context user_context['extras'].update(token_ref.get('extras', {})) user_context['method_names'].extend(token_ref.methods) except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def token_authenticate(context, auth_payload, user_context, token_ref): try: # Do not allow tokens used for delegation to # create another token, or perform any changes of # state in Keystone. To do so is to invite elevation of # privilege attacks if token_ref.oauth_scoped or token_ref.trust_scoped: raise exception.Forbidden() if not CONF.token.allow_rescope_scoped_token: # Do not allow conversion from scoped tokens. if token_ref.project_scoped or token_ref.domain_scoped: raise exception.Forbidden(action=_("rescope a scoped token")) wsgi.validate_token_bind(context, token_ref) # New tokens maintain the audit_id of the original token in the # chain (if possible) as the second element in the audit data # structure. Look for the last element in the audit data structure # which will be either the audit_id of the token (in the case of # a token that has not been rescoped) or the audit_chain id (in # the case of a token that has been rescoped). try: token_audit_id = token_ref.get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): In the case this is a token that was # issued prior to audit id existing, the chain is not tracked. token_audit_id = None user_context.setdefault('expires_at', token_ref.expires) user_context['audit_id'] = token_audit_id user_context.setdefault('user_id', token_ref.user_id) # TODO(morganfainberg: determine if token 'extras' can be removed # from the user_context user_context['extras'].update(token_ref.get('extras', {})) user_context['method_names'].extend(token_ref.methods) except AssertionError as e: LOG.error(six.text_type(e)) raise exception.Unauthorized(e)
def authenticate(self, context, auth_payload, user_context): try: if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target=METHOD_NAME) token_id = auth_payload['id'] token_ref = self.token_api.get_token(token_id) wsgi.validate_token_bind(context, token_ref) user_context.setdefault( 'user_id', token_ref['token_data']['token']['user']['id']) # to support Grizzly-3 to Grizzly-RC1 transition expires_at = token_ref['token_data']['token'].get( 'expires_at', token_ref['token_data']['token'].get('expires')) user_context.setdefault('expires_at', expires_at) user_context['extras'].update( token_ref['token_data']['token']['extras']) user_context['method_names'].extend( token_ref['token_data']['token']['methods']) if ('OS-TRUST:trust' in token_ref['token_data']['token'] or 'trust' in token_ref['token_data']['token']): raise exception.Forbidden() except AssertionError as e: LOG.error(e) raise exception.Unauthorized(e)
def _authenticate_token(self, request, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError( attribute='token', target='auth') if 'id' not in auth['token']: raise exception.ValidationError( attribute='id', target='token') old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: v3_token_data = self.token_provider_api.validate_token( old_token ) # NOTE(lbragstad): Even though we are not using the v2.0 token # reference after we translate it in v3_to_v2_token(), we still # need to perform that check. We have to do this because # v3_to_v2_token will ensure we don't use specific tokens only # attainable via v3 to get new tokens on v2.0. For example, an # exception would be raised if we passed a federated token to # v3_to_v2_token, because federated tokens aren't supported by # v2.0 (the same applies to OAuth tokens, domain-scoped tokens, # etc..). v2_helper = common.V2TokenDataHelper() v2_helper.v3_to_v2_token(v3_token_data, old_token) token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=v3_token_data ) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(request.context_dict, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(utils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = token_model_ref.expires if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = token_model_ref.bind audit_id = token_model_ref.audit_chain_id return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError( attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError( attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: old_token_ref = self.token_api.get_token(old_token) 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() if 'trust_id' in old_token_ref['metadata']: raise exception.Forbidden() user_ref = old_token_ref['user'] user_id = user_ref['id'] tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: trust_ref = self.trust_api.get_trust(auth['trust_id']) if trust_ref is None: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(timeutils.isotime()): raise exception.Forbidden()() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden()() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden()() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = old_token_ref['expires'] if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden()() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = old_token_ref.get('bind') # TODO(morganfainberg): Convert this over to using the KeystoneToken # model when removing dependency on token_api. token_data = old_token_ref.get('token_data') audit_id = None if token_data: # NOTE(morganfainberg): The token audit field will always contain # the token's direct audit id at index 0, index 1 will exist and # contain the audit chain id (audit id of the original token in # the chain), so always lookup the last element of the audit field # to determine the id to pass on. try: if 'access' in token_data: audit_id = token_data['access']['token'].get( 'audit_ids', [])[-1] else: audit_id = token_data['token'].get('audit_ids', [])[-1] except IndexError: # NOTE(morganfainberg): When transitioning from tokens without # audit_ids to tokens with audit ids it some tokens may not # have an audit_id, and the lookup will cause an IndexError # to be raised. pass return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if "token" not in auth: raise exception.ValidationError(attribute="token", target="auth") if "id" not in auth["token"]: raise exception.ValidationError(attribute="id", target="token") old_token = auth["token"]["id"] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute="token", size=CONF.max_token_size) try: old_token_ref = self.token_api.get_token(old_token) 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() if "trust_id" in old_token_ref["metadata"]: raise exception.Forbidden() user_ref = old_token_ref["user"] user_id = user_ref["id"] if not CONF.trust.enabled and "trust_id" in auth: raise exception.Forbidden("Trusts are disabled.") elif CONF.trust.enabled and "trust_id" in auth: trust_ref = self.trust_api.get_trust(auth["trust_id"]) if trust_ref is None: raise exception.Forbidden() if user_id != trust_ref["trustee_user_id"]: raise exception.Forbidden() if ("expires" in trust_ref) and (trust_ref["expires"]): expiry = trust_ref["expires"] if expiry < timeutils.parse_isotime(timeutils.isotime()): raise exception.Forbidden()() user_id = trust_ref["trustor_user_id"] trustor_user_ref = self.identity_api.get_user(trust_ref["trustor_user_id"]) if not trustor_user_ref["enabled"]: raise exception.Forbidden()() trustee_user_ref = self.identity_api.get_user(trust_ref["trustee_user_id"]) if not trustee_user_ref["enabled"]: raise exception.Forbidden()() if trust_ref["impersonation"] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) tenant_ref, metadata_ref["roles"] = self._get_project_roles_and_ref(user_id, tenant_id) expiry = old_token_ref["expires"] if CONF.trust.enabled and "trust_id" in auth: trust_id = auth["trust_id"] trust_roles = [] for role in trust_ref["roles"]: if "roles" not in metadata_ref: raise exception.Forbidden()() if role["id"] in metadata_ref["roles"]: trust_roles.append(role["id"]) else: raise exception.Forbidden() if "expiry" in trust_ref and trust_ref["expiry"]: trust_expiry = timeutils.parse_isotime(trust_ref["expiry"]) if trust_expiry < expiry: expiry = trust_expiry metadata_ref["roles"] = trust_roles metadata_ref["trustee_user_id"] = trust_ref["trustee_user_id"] metadata_ref["trust_id"] = trust_id bind = old_token_ref.get("bind", None) return (current_user_ref, tenant_ref, metadata_ref, expiry, bind)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError( attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError( attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=self.token_provider_api.validate_token(old_token)) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(context, token_model_ref) # A trust token cannot be used to get another token if token_model_ref.trust_scoped: raise exception.Forbidden() user_id = token_model_ref.user_id tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: trust_ref = self.trust_api.get_trust(auth['trust_id']) if trust_ref is None: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(timeutils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = token_model_ref.expires if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden()() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = token_model_ref.bind audit_id = token_model_ref.audit_chain_id return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError(attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=self.token_provider_api.validate_v2_token( old_token)) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(context, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(utils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = token_model_ref.expires if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = token_model_ref.bind audit_id = token_model_ref.audit_chain_id return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def _authenticate_token(self, request, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if 'id' not in auth['token']: raise exception.ValidationError(attribute='id', target='token') old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: v3_token_data = self.token_provider_api.validate_token(old_token) # NOTE(lbragstad): Even though we are not using the v2.0 token # reference after we translate it in v3_to_v2_token(), we still # need to perform that check. We have to do this because # v3_to_v2_token will ensure we don't use specific tokens only # attainable via v3 to get new tokens on v2.0. For example, an # exception would be raised if we passed a federated token to # v3_to_v2_token, because federated tokens aren't supported by # v2.0 (the same applies to OAuth tokens, domain-scoped tokens, # etc..). v2_helper = common.V2TokenDataHelper() v2_helper.v3_to_v2_token(v3_token_data, old_token) token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=v3_token_data) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(request.context_dict, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(utils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = token_model_ref.expires if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = token_model_ref.bind audit_id = token_model_ref.audit_chain_id return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def authenticate(self, request, auth): """Try to authenticate using an already existing token. :param request: A request object. :param auth: Dictionary representing the authentication request. :returns: A tuple containing the user reference, project identifier, token expiration, bind information, and original audit information. """ if 'token' not in auth: raise exception.ValidationError( attribute='token', target='auth') if 'id' not in auth['token']: raise exception.ValidationError( attribute='id', target='token') old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: v3_token_data = self.token_provider_api.validate_token( old_token ) # NOTE(lbragstad): Even though we are not using the v2.0 token # reference after we translate it in v3_to_v2_token(), we still # need to perform that check. We have to do this because # v3_to_v2_token will ensure we don't use specific tokens only # attainable via v3 to get new tokens on v2.0. For example, an # exception would be raised if we passed a federated token to # v3_to_v2_token, because federated tokens aren't supported by # v2.0 (the same applies to OAuth tokens, domain-scoped tokens, # etc..). v2_helper = V2TokenDataHelper() v2_helper.v3_to_v2_token(v3_token_data, old_token) token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=v3_token_data ) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(request.context_dict, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id project_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() # If a trust is being used to obtain access to another project and # the other project doesn't match the project in the trust, we need # to bail because trusts are only good up to a single project. if (trust_ref['project_id'] and project_id != trust_ref['project_id']): raise exception.Forbidden() expiry = token_model_ref.expires user_ref = self.identity_api.get_user(user_id) bind = token_model_ref.bind original_audit_id = token_model_ref.audit_chain_id return (user_ref, project_id, expiry, bind, original_audit_id)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError(attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: old_token_ref = self.token_api.get_token(old_token) 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() if 'trust_id' in old_token_ref['metadata']: raise exception.Forbidden() user_ref = old_token_ref['user'] user_id = user_ref['id'] tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: trust_ref = self.trust_api.get_trust(auth['trust_id']) if trust_ref is None: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(timeutils.isotime()): raise exception.Forbidden()() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden()() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden()() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = old_token_ref['expires'] if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden()() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = old_token_ref.get('bind') return (current_user_ref, tenant_ref, metadata_ref, expiry, bind)
def authenticate(self, request, auth): """Try to authenticate using an already existing token. :param request: A request object. :param auth: Dictionary representing the authentication request. :returns: A tuple containing the user reference, project identifier, token expiration, bind information, and original audit information. """ if 'token' not in auth: raise exception.ValidationError( attribute='token', target='auth') if 'id' not in auth['token']: raise exception.ValidationError( attribute='id', target='token') old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: v3_token_data = self.token_provider_api.validate_token( old_token ) # NOTE(lbragstad): Even though we are not using the v2.0 token # reference after we translate it in v3_to_v2_token(), we still # need to perform that check. We have to do this because # v3_to_v2_token will ensure we don't use specific tokens only # attainable via v3 to get new tokens on v2.0. For example, an # exception would be raised if we passed a federated token to # v3_to_v2_token, because federated tokens aren't supported by # v2.0 (the same applies to OAuth tokens, domain-scoped tokens, # etc..). v2_helper = common.V2TokenDataHelper() v2_helper.v3_to_v2_token(v3_token_data, old_token) token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=v3_token_data ) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(request.context_dict, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id project_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() # If a trust is being used to obtain access to another project and # the other project doesn't match the project in the trust, we need # to bail because trusts are only good up to a single project. if (trust_ref['project_id'] and project_id != trust_ref['project_id']): raise exception.Forbidden() expiry = token_model_ref.expires user_ref = self.identity_api.get_user(user_id) bind = token_model_ref.bind original_audit_id = token_model_ref.audit_chain_id return (user_ref, project_id, expiry, bind, original_audit_id)