예제 #1
0
    def authenticate_for_token(self, request, auth=None):
        """Authenticate user and issue a token."""
        include_catalog = 'nocatalog' not in request.params

        validate_issue_token_auth(auth)

        try:
            auth_info = core.AuthInfo.create(auth=auth)
            auth_context = core.AuthContext(extras={},
                                            method_names=[],
                                            bind={})
            self.authenticate(request, auth_info, auth_context)
            if auth_context.get('access_token_id'):
                auth_info.set_scope(None, auth_context['project_id'], None)
            self._check_and_set_default_scoping(auth_info, auth_context)
            (domain_id, project_id, trust, unscoped,
             system) = (auth_info.get_scope())

            # NOTE(notmorgan): only methods that actually run and succeed will
            # be in the auth_context['method_names'] list. Do not blindly take
            # the values from auth_info, look at the authoritative values. Make
            # sure the set is unique.
            method_names_set = set(auth_context.get('method_names', []))
            method_names = list(method_names_set)

            # Do MFA Rule Validation for the user
            if not self._mfa_rules_validator.check_auth_methods_against_rules(
                    auth_context['user_id'], method_names_set):
                raise exception.InsufficientAuthMethods(
                    user_id=auth_context['user_id'],
                    methods='[%s]' % ','.join(auth_info.get_method_names()))

            expires_at = auth_context.get('expires_at')
            token_audit_id = auth_context.get('audit_id')

            is_domain = auth_context.get('is_domain')
            (token_id, token_data) = self.token_provider_api.issue_token(
                auth_context['user_id'],
                method_names,
                expires_at=expires_at,
                system=system,
                project_id=project_id,
                is_domain=is_domain,
                domain_id=domain_id,
                auth_context=auth_context,
                trust=trust,
                include_catalog=include_catalog,
                parent_audit_id=token_audit_id)

            # NOTE(wanghong): We consume a trust use only when we are using
            # trusts and have successfully issued a token.
            if trust:
                self.trust_api.consume_use(trust['id'])

            return render_token_data_response(token_id,
                                              token_data,
                                              created=True)
        except exception.TrustNotFound as e:
            LOG.warning(six.text_type(e))
            raise exception.Unauthorized(e)
예제 #2
0
def authenticate_for_token(auth=None):
    """Authenticate user and issue a token."""
    try:
        auth_info = core.AuthInfo.create(auth=auth)
        auth_context = core.AuthContext(method_names=[],
                                        bind={})
        authenticate(auth_info, auth_context)
        if auth_context.get('access_token_id'):
            auth_info.set_scope(None, auth_context['project_id'], None)
        _check_and_set_default_scoping(auth_info, auth_context)
        (domain_id, project_id, trust, unscoped, system) = (
            auth_info.get_scope()
        )
        trust_id = trust.get('id') if trust else None

        receipt = receipt_handlers.extract_receipt(auth_context)

        # NOTE(notmorgan): only methods that actually run and succeed will
        # be in the auth_context['method_names'] list. Do not blindly take
        # the values from auth_info, look at the authoritative values. Make
        # sure the set is unique.
        # NOTE(adriant): The set of methods will also include any methods from
        # the given receipt.
        if receipt:
            method_names_set = set(
                auth_context.get('method_names', []) + receipt.methods)
        else:
            method_names_set = set(auth_context.get('method_names', []))
        method_names = list(method_names_set)

        app_cred_id = None
        if 'application_credential' in method_names:
            token_auth = auth_info.auth['identity']
            app_cred_id = token_auth['application_credential']['id']

        # Do MFA Rule Validation for the user
        if not core.UserMFARulesValidator.check_auth_methods_against_rules(
                auth_context['user_id'], method_names_set):
            raise exception.InsufficientAuthMethods(
                user_id=auth_context['user_id'],
                methods=method_names)

        expires_at = auth_context.get('expires_at')
        token_audit_id = auth_context.get('audit_id')

        token = PROVIDERS.token_provider_api.issue_token(
            auth_context['user_id'], method_names, expires_at=expires_at,
            system=system, project_id=project_id, domain_id=domain_id,
            auth_context=auth_context, trust_id=trust_id,
            app_cred_id=app_cred_id, parent_audit_id=token_audit_id)

        # NOTE(wanghong): We consume a trust use only when we are using
        # trusts and have successfully issued a token.
        if trust:
            PROVIDERS.trust_api.consume_use(token.trust_id)

        return token
    except exception.TrustNotFound as e:
        LOG.warning(e)
        raise exception.Unauthorized(e)
예제 #3
0
 def test_token_is_cached(self):
     # Make sure we only call PROVIDERS.token_provider_api.validate_token()
     # once while in middleware so that we're mindful of performance
     context = auth_core.AuthContext(user_id=self.user['id'],
                                     methods=['password'])
     token = PROVIDERS.token_provider_api.issue_token(
         context['user_id'],
         context['methods'],
         project_id=self.project_id,
         auth_context=context)
     headers = {authorization.AUTH_TOKEN_HEADER: token.id.encode('utf-8')}
     with mock.patch.object(PROVIDERS.token_provider_api,
                            'validate_token',
                            return_value=token) as token_mock:
         self._do_middleware_request(path='/v3/projects',
                                     method='get',
                                     headers=headers)
         token_mock.assert_called_once()