Beispiel #1
0
    def get_plugin(self,
                   service_provider=None,
                   auth_url=None,
                   plugins=[],
                   **kwargs):
        """Authenticate using keystone to keystone federation.

        This plugin uses other v3 plugins to authenticate a user to a
        identity provider in order to authenticate the user to a service
        provider

        :param service_provider: service provider ID
        :param auth_url: Keystone auth url
        :param plugins: list of openstack_auth plugins to check
        :returns Keystone2Keystone keystone auth plugin
        """

        # service_provider being None prevents infinite recursion
        if utils.get_keystone_version() < 3 or not service_provider:
            return None

        keystone_idp_id = getattr(settings, 'KEYSTONE_PROVIDER_IDP_ID',
                                  'localkeystone')
        if service_provider == keystone_idp_id:
            return None

        for plugin in plugins:
            unscoped_idp_auth = plugin.get_plugin(plugins=plugins,
                                                  auth_url=auth_url,
                                                  **kwargs)
            if unscoped_idp_auth:
                break
        else:
            LOG.debug('Could not find base authentication backend for '
                      'K2K plugin with the provided credentials.')
            return None

        idp_exception = None
        scoped_idp_auth = None
        unscoped_auth_ref = base.BasePlugin.get_access_info(
            self, unscoped_idp_auth)
        try:
            scoped_idp_auth, __ = self.get_project_scoped_auth(
                unscoped_idp_auth, unscoped_auth_ref)
        except exceptions.KeystoneAuthException as idp_excp:
            idp_exception = idp_excp

        if not scoped_idp_auth or idp_exception:
            msg = 'Identity provider authentication Failed.'
            raise exceptions.KeystoneAuthException(msg)

        session = utils.get_session()

        if scoped_idp_auth.get_sp_auth_url(session, service_provider) is None:
            msg = _('Could not find service provider ID on Keystone.')
            raise exceptions.KeystoneAuthException(msg)

        unscoped_auth = v3_auth.Keystone2Keystone(
            base_plugin=scoped_idp_auth, service_provider=service_provider)
        return unscoped_auth
Beispiel #2
0
    def test_switch_keystone_provider_remote(self):
        auth_url = settings.OPENSTACK_KEYSTONE_URL
        target_provider = 'k2kserviceprovider'
        self.data = data_v3.generate_test_data(service_providers=True)
        self.sp_data = data_v3.generate_test_data(endpoint='http://sp2')
        projects = [self.data.project_one, self.data.project_two]
        domains = []
        user = self.data.user
        unscoped = self.data.unscoped_access_info
        form_data = self.get_form_data(user)

        # mock authenticate
        self._mock_unscoped_and_domain_list_projects(user, projects)
        self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id)

        # mock switch
        plugin = v3_auth.Token(auth_url=auth_url,
                               token=unscoped.auth_token,
                               project_id=None,
                               reauthenticate=False)
        plugin.get_access(mox.IsA(session.Session)).AndReturn(
            self.data.unscoped_access_info)

        plugin.auth_url = auth_url
        client = self.ks_client_module.Client(session=mox.IsA(session.Session),
                                              auth=plugin)

        self._mock_unscoped_list_projects(client, user, projects)
        plugin = self._create_token_auth(
            self.data.project_one.id,
            token=self.data.unscoped_access_info.auth_token,
            url=settings.OPENSTACK_KEYSTONE_URL)
        plugin.get_access(mox.IsA(session.Session)).AndReturn(
            settings.OPENSTACK_KEYSTONE_URL)

        plugin.get_sp_auth_url(
            mox.IsA(session.Session), target_provider
        ).AndReturn('https://k2kserviceprovider/sp_url')
        plugin = v3_auth.Keystone2Keystone(base_plugin=plugin,
                                           service_provider=target_provider)
        plugin.get_access(mox.IsA(session.Session)). \
            AndReturn(self.sp_data.unscoped_access_info)
        plugin.auth_url = 'http://service_provider_endp:5000/v3'

        # mock authenticate for service provider
        sp_projects = [self.sp_data.project_one, self.sp_data.project_two]
        sp_unscoped = self.sp_data.federated_unscoped_access_info
        sp_unscoped_auth = self._mock_plugin(sp_unscoped,
                                             auth_url=plugin.auth_url)
        client = self._mock_unscoped_token_client(None, plugin.auth_url,
                                                  plugin=sp_unscoped_auth)
        self._mock_unscoped_list_domains(client, domains)
        client = self._mock_unscoped_token_client(None, plugin.auth_url,
                                                  plugin=sp_unscoped_auth)
        self._mock_unscoped_federated_list_projects(client, sp_projects)
        self._mock_scoped_client_for_tenant(sp_unscoped,
                                            self.sp_data.project_one.id,
                                            url=plugin.auth_url,
                                            token=sp_unscoped.auth_token)

        self.mox.ReplayAll()

        # Log in
        url = reverse('login')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        response = self.client.post(url, form_data)
        self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)

        # Switch
        url = reverse('switch_keystone_provider', args=[target_provider])
        form_data['keystone_provider'] = target_provider
        response = self.client.get(url, form_data, follow=True)
        self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)

        # Assert keystone provider has changed
        self.assertEqual(self.client.session['keystone_provider_id'],
                         target_provider)
        # These should not change
        self.assertEqual(self.client.session['k2k_base_unscoped_token'],
                         unscoped.auth_token)
        self.assertEqual(self.client.session['k2k_auth_url'], auth_url)
Beispiel #3
0
 def get_plugin(self, **kwargs):
     kwargs.setdefault('base_plugin', self._get_base_plugin())
     kwargs.setdefault('service_provider', self.SP_ID)
     return v3.Keystone2Keystone(**kwargs)
Beispiel #4
0
    def test_switch_keystone_provider_remote_fail(self):
        target_provider = 'k2kserviceprovider'
        self.data = data_v3.generate_test_data(service_providers=True)
        self.sp_data = data_v3.generate_test_data(endpoint='http://sp2')
        projects = [self.data.project_one, self.data.project_two]
        user = self.data.user
        form_data = self.get_form_data(user)

        plugin = v3_auth.Password(
            auth_url=settings.OPENSTACK_KEYSTONE_URL,
            password=self.data.user.password,
            username=self.data.user.name,
            user_domain_name=DEFAULT_DOMAIN,
            unscoped=True)
        plugin.get_access(mox.IsA(session.Session)). \
            AndReturn(self.data.unscoped_access_info)
        plugin.auth_url = settings.OPENSTACK_KEYSTONE_URL
        client = self.ks_client_module.Client(
            session=mox.IsA(session.Session), auth=plugin)

        plugin = v3_auth.Token(
            auth_url=settings.OPENSTACK_KEYSTONE_URL,
            token=self.data.unscoped_access_info.auth_token,
            domain_name=DEFAULT_DOMAIN,
            reauthenticate=False)
        plugin.get_access(mox.IsA(session.Session)).AndReturn(
            self.data.domain_scoped_access_info)

        client.projects = self.mox.CreateMockAnything()
        client.projects.list(user=user.id).AndReturn(projects)

        plugin = v3_auth.Token(
            auth_url=settings.OPENSTACK_KEYSTONE_URL,
            token=self.data.unscoped_access_info.auth_token,
            project_id=self.data.project_one.id,
            reauthenticate=False)
        self.scoped_token_auth = plugin
        plugin.get_access(mox.IsA(session.Session)).AndReturn(
            self.data.unscoped_access_info)
        self.ks_client_module.Client(
            session=mox.IsA(session.Session),
            auth=plugin)

        # mock switch
        plugin = v3_auth.Token(
            auth_url=settings.OPENSTACK_KEYSTONE_URL,
            token=self.data.unscoped_access_info.auth_token,
            project_id=None,
            reauthenticate=False)
        plugin.get_access(mox.IsA(session.Session)).AndReturn(
            self.data.unscoped_access_info)
        plugin.auth_url = settings.OPENSTACK_KEYSTONE_URL
        client = self.ks_client_module.Client(session=mox.IsA(session.Session),
                                              auth=plugin)

        client.projects = self.mox.CreateMockAnything()
        client.projects.list(user=user.id).AndReturn(projects)

        plugin = v3_auth.Token(
            auth_url=settings.OPENSTACK_KEYSTONE_URL,
            token=self.data.unscoped_access_info.auth_token,
            project_id=self.data.project_one.id,
            reauthenticate=False)
        plugin.get_access(mox.IsA(session.Session)).AndReturn(
            settings.OPENSTACK_KEYSTONE_URL)
        plugin.get_sp_auth_url(
            mox.IsA(session.Session), target_provider
        ).AndReturn('https://k2kserviceprovider/sp_url')

        # let the K2K plugin fail when logging in
        plugin = v3_auth.Keystone2Keystone(
            base_plugin=plugin, service_provider=target_provider)
        plugin.get_access(mox.IsA(session.Session)).AndRaise(
            keystone_exceptions.AuthorizationFailure)
        self.mox.ReplayAll()

        # Log in
        url = reverse('login')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        response = self.client.post(url, form_data)
        self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)

        # Switch
        url = reverse('switch_keystone_provider', args=[target_provider])
        form_data['keystone_provider'] = target_provider
        response = self.client.get(url, form_data, follow=True)
        self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)

        # Assert that provider has not changed because of failure
        self.assertEqual(self.client.session['keystone_provider_id'],
                         'localkeystone')
        # These should never change
        self.assertEqual(self.client.session['k2k_base_unscoped_token'],
                         self.data.unscoped_access_info.auth_token)
        self.assertEqual(self.client.session['k2k_auth_url'],
                         settings.OPENSTACK_KEYSTONE_URL)