Keystone REMOTE_USER with no metadata causes 404 on auth

Bug #1075710 reported by Boden R
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Invalid
Medium
Unassigned

Bug Description

With the recent introduction of REMOTE_USER auth support (i.e. remote authn) in Keystone (see https://review.openstack.org/#/c/14823), there's a new bug under the following conditions:

* REMOTE_USER is set by an external authenticator
* There is no 'metadata' (i.e. no metadata for the given user in the given tenant)

When the above conditions are true, the following error is returned on a POST to /tokens -->

2012-11-05 14:30:37 DEBUG [keystone.common.wsgi] ******************** RESPONSE BODY ********************
2012-11-05 14:30:37 DEBUG [keystone.common.wsgi] {"error": {"message": "An unhandled exception has occurred: Could not find metadata.", "code": 404, "title": "Not Found"}}
2012-11-05 14:30:37 DEBUG [eventlet.wsgi.server] 172.17.0.8 - - [05/Nov/2012 14:30:37] "POST /v2.0/tokens HTTP/1.1" 404 282 0.103857

The root cause is located around line 358 of service.py where the 'else' branch to handle remote authn tries to use a tenant_ref and metadata_ref. In this scenario the call to self.identity_api.get_metadata(...) throws an exception.MetadataNotFound exception which is not handled in service.py.

If you look in one of the identity drivers (say the sql driver), you can see in the typical authenticate() flow the driver handles the exception and defaults the meta. From the sql identity driver:

        if tenant_id is not None:
            if tenant_id not in self.get_tenants_for_user(user_id):
                raise AssertionError('Invalid tenant')

            try:
                tenant_ref = self.get_tenant(tenant_id)
                metadata_ref = self.get_metadata(user_id, tenant_id)
            except exception.TenantNotFound:
                tenant_ref = None
                metadata_ref = {}
            except exception.MetadataNotFound:
                metadata_ref = {}

        return (filter_user(user_ref), tenant_ref, metadata_ref)

That said, one fix for this bug is to update service.py to wrap the root error cause in a try/except.

Below is a diff including a test case that reproduces the error and the fix:

diff --git a/keystone/service.py b/keystone/service.py
index b6443a7..1e55348 100644
--- a/keystone/service.py
+++ b/keystone/service.py
@@ -355,14 +355,19 @@ class TokenController(wsgi.Application):
                             self.identity_api,
                             user_id)
                     if tenant_id:
- if not tenant_ref:
- tenant_ref = self.identity_api.get_tenant(
+ try:
+ if not tenant_ref:
+ tenant_ref = self.identity_api.get_tenant(
+ self.identity_api,
+ tenant_id)
+ metadata_ref = self.identity_api.get_metadata(
                                 self.identity_api,
+ user_id,
                                 tenant_id)
- metadata_ref = self.identity_api.get_metadata(
- self.identity_api,
- user_id,
- tenant_id)
+ except (exception.TenantNotFound,
+ exception.MetadataNotFound):
+ pass
+
                     auth_info = (user_ref, tenant_ref, metadata_ref)

                 # If the user is disabled don't allow them to authenticate
diff --git a/tests/test_service.py b/tests/test_service.py
index 775b2ca..d9d3c17 100644
--- a/tests/test_service.py
+++ b/tests/test_service.py
@@ -129,3 +129,16 @@ class RemoteUserTest(test.TestCase):
             self.api.authenticate,
             {'REMOTE_USER': 'FOOZBALL'},
             self._build_user_auth('FOO', 'nosir', 'BAR'))
+
+ def test_remote_auth_no_metadata(self):
+ for meta in default_fixtures.METADATA:
+ self.identity_api.delete_metadata(
+ meta['user_id'],
+ meta['tenant_id'])
+ local_token = self.api.authenticate(
+ {},
+ self._build_user_auth('FOO', 'foo2', 'BAR'))
+ remote_token = self.api.authenticate(
+ {'REMOTE_USER': 'FOO'},
+ self._build_user_auth('FOO', 'nosir', 'BAR'))
+ self.assertEqualTokens(local_token, remote_token)

Joseph Heck (heckj)
Changed in keystone:
status: New → Triaged
importance: Undecided → Medium
Revision history for this message
Davanum Srinivas (DIMS) (dims-v) wrote :

Looks like this is already fixed in latest keystone v3. There is a try/catch in _get_metadata_ref and _get_tenant_ref - https://github.com/openstack/keystone/blob/master/keystone/service.py

-- dims

Revision history for this message
Alvaro Lopez (aloga) wrote :

This was already fixed on https://review.openstack.org/#/c/15403/

Changed in keystone:
status: Triaged → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.